home *** CD-ROM | disk | FTP | other *** search
/ Zoom 2 / Zoom - Release 2 (1996)(Active Software)[!].iso / music / utilities / octamed4devkit / proplayer / proplayer_special.a < prev    next >
Text File  |  1994-03-02  |  107KB  |  3,116 lines

  1. ; SPECIAL VERSION FOR Mark Knight at Mindscape
  2. ; Search for the string 'SPECIAL...' to find things changed from
  3. ; the standard proplayer.a version.
  4. ; © RBF Software 1994
  5. ; As with the rest of this disks contents,NOT for release as public domain.
  6. ; However, the routine may be used within programs that are released as
  7. ; public domain, ( no charge ).
  8. ; As with the rest of the routines on this disk, If intended for use within
  9. ; a commercial or chargeable program, you must register, ( see licencing ).
  10.  
  11. ;============================================================================
  12. ;   proplayer.a
  13. ;   ~~~~~~~~~~~
  14. ; $VER: proplayer 5.004 (09.06.1993)
  15. ;
  16. ; The music player routine for MMD0/MMD1/MMD2 MED/OctaMED
  17. ; four-channel modules.
  18. ;
  19. ; Written by Teijo Kinnunen.
  20. ; If you find bugs in this routine, please notify:
  21. ;   Teijo Kinnunen
  22. ;   Oksantie 19
  23. ;   FIN-86300  OULAINEN
  24. ;   FINLAND
  25. ;
  26. ;============================================================================
  27.  
  28. ;****** Feature control ******
  29. ;
  30. MIDI        EQU 0   ;1 = include MIDI code
  31. AUDDEV      EQU 1   ;1 = allocate channels using audio.device
  32. SYNTH       EQU 1   ;1 = include synth-sound handler
  33. CHECK       EQU 1   ;1 = do range checkings (track, sample in mem etc.)
  34. RELVOL      EQU 1   ;1 = include relative volume handling code
  35. IFFMOCT     EQU 1   ;1 = play IFF multi-octave samples/ExtSamples correctly
  36. HOLD        EQU 1   ;1 = handle hold/decay
  37. PLAYMMD0    EQU 1   ;1 = play old MMD0 modules
  38. ;
  39. ; The less features you include, the faster and shorter the play-routine
  40. ; will be.
  41.  
  42. ;****** Timing control ******
  43. ;
  44. VBLANK  EQU 0   ;1 = use VBlank interrupt (when absolutely necessary)
  45. CIAB    EQU 1   ;1 = use CIA timers (default)
  46. ;
  47. ; Please use CIAB whenever possible to avoid problems with variable
  48. ; VBlank speeds and to allow the use of command F01 - FF0 (set tempo)
  49. ; If both are set to 0, the timing is left for you (never set both to 1!!),
  50. ; then you just call _IntHandler for each timing pulse.
  51.  
  52. ;============================================================================
  53.  
  54. ;If you are making a demo/game with only a single tune you'd like to
  55. ;incorporate in the code (like "easyplayer.a" of MED V3), set the following
  56. ;flag to 1. This requires an assembler with INCBIN (or equivalent) directive.
  57. ;You have to type the module name into the INCBIN statement (located near the
  58. ;end of this file, on line 2052).
  59.  
  60. EASY    EQU 0
  61.  
  62. ;Call _startmusic to play the music, and _endmusic to stop it (before
  63. ;exiting). Note: don't call _startmusic twice!! This would cause the module
  64. ;to be relocated twice (= Guru). If you need to stop and continue playing,
  65. ;don't use the EASY routines, use PlayModule/StopPlayer... instead.
  66.  
  67. ;============================================================================
  68.  
  69. ; The MMD structure offsets
  70. mmd_id      EQU 0
  71. mmd_modlen  EQU 4
  72. mmd_songinfo    EQU 8
  73. ; these two for MMD2s only!
  74. mmd_psecnum EQU 12
  75. mmd_pseq    EQU 14
  76. ;
  77. mmd_blockarr    EQU 16
  78. mmd_smplarr EQU 24
  79. mmd_expdata EQU 32
  80. mmd_pstate  EQU 40 ; <0 = play song, 0 = don't play, >0 = play block
  81. mmd_pblock  EQU 42
  82. mmd_pline   EQU 44
  83. mmd_pseqnum EQU 46
  84. mmd_counter EQU 50
  85. mmd_songsleft   EQU 51
  86.  
  87. ; The Song structure
  88. ; Instrument data here (504 bytes = 63 * 8)
  89. msng_numblocks  EQU 504
  90. msng_songlen    EQU 506
  91. msng_playseq    EQU 508
  92. msng_deftempo   EQU 764
  93. msng_playtransp EQU 766
  94. msng_flags  EQU 767
  95. msng_flags2 EQU 768
  96. msng_tempo2 EQU 769
  97. ; msng_trkvol applies to MMD0/MMD1 only.
  98. msng_trkvol EQU 770
  99. msng_mastervol  EQU 786
  100. msng_numsamples EQU 787
  101. ; Fields below apply to MMD2 modules only.
  102. msng_pseqs  EQU 508
  103. msng_sections   EQU 512
  104. msng_trkvoltbl  EQU 516
  105. msng_numtracks  EQU 520
  106. msng_numpseqs   EQU 522
  107.  
  108. ; Instrument data
  109. inst_repeat EQU 0
  110. inst_replen EQU 2
  111. inst_midich EQU 4
  112. inst_midipreset EQU 5
  113. inst_svol   EQU 6
  114. inst_strans EQU 7
  115.  
  116. ; Audio hardware offsets
  117. ac_ptr  EQU $00
  118. ac_len  EQU $04
  119. ac_per  EQU $06
  120. ac_vol  EQU $08
  121.  
  122. ; Trackdata sizes
  123. T03SZ   EQU 98
  124. T415SZ  EQU 20
  125.  
  126. ; Maximum number of tracks allowed. If you don't need this much tracks,
  127. ; you can decrease the number to save some space. (Be sure that the
  128. ; song really has no more than MAX_NUMTRACKS tracks. Minimum allowed
  129. ; value = 4.)
  130. MAX_NUMTRACKS   EQU 64
  131.  
  132. ; This value is used for MMD0/1 conversion. If MAX_NUMTRACKS <= 16,
  133. ; this should be the same. If MAX_NUMTRACKS > 16, this should be 16.
  134. MAX_MMD1_TRACKS EQU 16
  135.  
  136.         SECTION "text",CODE
  137.  
  138.     IFNE    EASY
  139.  
  140.         XDEF    _startmusic,_endmusic
  141.  
  142. _startmusic lea easymod,a2
  143.         bsr.s   _RelocModule
  144.         bsr.w   _InitPlayer
  145.         lea easymod,a0
  146.         bra.w   _PlayModule
  147.  
  148. _endmusic   bra.w   _RemPlayer
  149. ; ***** The relocation routine *****
  150. reloci      move.l  24(a2),d0
  151.         beq.s   xloci
  152.         movea.l d0,a0
  153.         moveq   #0,d0
  154.         move.b  msng_numsamples(a1),d0  ;number of samples
  155.         subq.b  #1,d0
  156. relocs:     bsr.s   relocentr
  157.         move.l  -4(a0),d3   ;sample ptr
  158.         beq.s   nosyn
  159.         move.l  d3,a3
  160.         tst.w   4(a3)
  161.         bpl.s   nosyn       ;type >= 0
  162.         move.w  20(a3),d2   ;number of waveforms
  163.         lea 278(a3),a3  ;ptr to wf ptrs
  164.         subq.w  #1,d2
  165. relsyn      add.l   d3,(a3)+
  166.         dbf d2,relsyn
  167. nosyn       dbf     d0,relocs
  168. xloci       rts
  169. norel       addq.l  #4,a0
  170.         rts
  171. relocentr   tst.l   (a0)
  172.         beq.s   norel
  173.         add.l   d1,(a0)+
  174.         rts
  175. _RelocModule    movem.l a2-a3/d2-d3,-(sp)
  176.         move.l  a2,d1       ;d1 = ptr to start of module
  177.         bsr.s   relocp
  178.         movea.l 8(a2),a1
  179.         bsr.s   reloci
  180. rel_lp      bsr.s   relocb
  181.         cmp.b   #'2',3(a2)  ;MMD2?
  182.         bne.s   norelmmd2
  183.         bsr.w   relocmmd2sng
  184. norelmmd2   move.l  32(a2),d0   ;extension struct
  185.         beq.s   rel_ex
  186.         move.l  d0,a0
  187.         bsr.s   relocentr   ;ptr to next module
  188.         bsr.s   relocentr   ;InstrExt...
  189.         addq.l  #4,a0       ;skip sizes of InstrExt
  190.         bsr.s   relocentr   ;annotxt
  191.         addq.l  #4,a0       ;annolen
  192.         bsr.s   relocentr   ;InstrInfo
  193.         addq.l  #8,a0
  194.         bsr.s   relocentr   ;rgbtable (not useful for most people)
  195.         addq.l  #4,a0       ;skip channelsplit
  196.         bsr.s   relocentr   ;NotationInfo
  197.         bsr.s   relocentr   ;songname
  198.         addq.l  #4,a0       ;skip song name length
  199.         bsr.s   relocentr   ;MIDI dumps
  200.         bsr.s   relocmdd
  201.         move.l  d0,a0
  202.         move.l  (a0),d0
  203.         beq.s   rel_ex
  204.         move.l  d0,a2
  205.         bsr.s   relocp
  206.         movea.l 8(a2),a1
  207.         bra.s   rel_lp
  208. rel_ex      movem.l (sp)+,d2-d3/a2-a3
  209.         rts
  210. relocp      lea 8(a2),a0
  211.         bsr.s   relocentr
  212.         addq.l  #4,a0
  213.         bsr.s   relocentr
  214.         addq.l  #4,a0
  215.         bsr.s   relocentr
  216.         addq.l  #4,a0
  217.         bra.s   relocentr
  218. relocb      move.l  16(a2),d0
  219.         beq.s   xlocb
  220.         movea.l d0,a0
  221.         move.w  msng_numblocks(a1),d0
  222.         subq.b  #1,d0
  223. rebl        bsr.s   relocentr
  224.         dbf     d0,rebl
  225.         cmp.b   #'T',3(a2)
  226.         beq.s   xlocb
  227.         cmp.b   #'1',3(a2)  ;test MMD type
  228.         bge.s   relocbi
  229. xlocb       rts
  230. relocmdd    tst.l   -(a0)
  231.         beq.s   xlocmdd
  232.         movea.l (a0),a0
  233.         move.w  (a0),d0     ;# of msg dumps
  234.         addq.l  #8,a0
  235. mddloop     beq.s   xlocmdd
  236.         bsr relocentr
  237.         bsr.s   relocdmp
  238.         subq.w  #1,d0
  239.         bra.s   mddloop
  240. xlocmdd     rts
  241. relocdmp    move.l  -4(a0),d3
  242.         beq.s   xlocdmp
  243.         exg.l   a0,d3       ;save
  244.         addq.l  #4,a0
  245.         bsr relocentr   ;reloc data pointer
  246.         move.l  d3,a0       ;restore
  247. xlocdmp     rts
  248. relocbi     move.w  msng_numblocks(a1),d0
  249.         move.l  a0,a3
  250. biloop      subq.w  #1,d0
  251.         bmi.s   xlocdmp
  252.         move.l  -(a3),a0
  253.         addq.l  #4,a0
  254.         bsr relocentr   ;BlockInfo ptr
  255.         tst.l   -(a0)
  256.         beq.s   biloop
  257.         move.l  (a0),a0
  258.         bsr relocentr   ;hldata
  259.         bsr relocentr   ;block name
  260.         bra.s   biloop
  261. ; take care of the new features of MMD2s
  262. relocmmd2sng    move.l  mmd_songinfo(a2),a0
  263.         lea msng_pseqs(a0),a0
  264.         bsr relocentr   ;playseqtable
  265.         bsr relocentr   ;sectiontable
  266.         bsr relocentr   ;trackvols
  267.         move.w  2(a0),d0    ;numpseqs
  268.         move.l  -12(a0),a0  ;get back to playseqtable
  269.         subq.w  #1,d0
  270. psqtblloop  bsr relocentr
  271.         dbf d0,psqtblloop
  272.         rts
  273.     ENDC
  274.  
  275.  
  276. ; -------- _ChannelOff: Turn off a channel -------------------------------
  277. _ChannelOff:    ;d0 = channel #
  278.         lea DB,a0
  279.         lea trackdataptrs-DB(a0),a1
  280.         lsl.w   #2,d0
  281.         adda.w  d0,a1
  282.         lsr.w   #2,d0
  283.         movea.l (a1),a1
  284.     IFNE    MIDI
  285.         move.b  trk_prevmidin(a1),d1    ;first: is it MIDI??
  286.         beq.s   notcomidi   ;not a midi note
  287. ; -------- TURN OFF MIDI TRACK -------------------------------------------
  288.         lea noteondata-DB(a0),a0
  289. choff_midi: clr.b   trk_prevmidin(a1)
  290.         move.b  d1,1(a0)
  291.         bmi.s   notamigatrk
  292.         move.b  trk_prevmidich(a1),(a0) ;prev midi channel
  293.         clr.b   2(a0)
  294.         or.b    #$90,(a0)       ;note off
  295.         moveq   #3,d0
  296.         bra.w   _AddMIDIData
  297.     ENDC
  298. notcomidi:  cmp.b   #4,d0
  299.         bge.s   notamigatrk
  300. ; -------- TURN OFF AMIGA-CHANNEL ----------------------------------------
  301.     IFNE    SYNTH
  302.         clr.l   trk_synthptr(a1)
  303.         clr.b   trk_synthtype(a1)
  304.     ENDC
  305.         clr.w   trk_soffset(a1)
  306.         moveq   #1,d1
  307.         lsl.w   d0,d1
  308.         move.w  d1,$dff096
  309. notamigatrk:    rts
  310.  
  311. ; -------- SoundOff: Turn off all channels -------------------------------
  312. SoundOff:   move.l  d2,-(sp)
  313.         moveq   #MAX_NUMTRACKS-1,d2
  314. SO_loop0    move.l  d2,d0
  315.         bsr.s   _ChannelOff
  316.         dbf d2,SO_loop0
  317.         clr.l   _module     ;play nothing
  318.         move.l  (sp)+,d2
  319. SO_rts      rts
  320.  
  321. ; -------- _PlayNote: The note playing routine ---------------------------
  322. _PlayNote:  ;d7(w) = trk #, d1 = note #, d3(w) = instr # a3 = addr of instr
  323. ; -------- CHECK INSTRUMENT (existence, type) ----------------------------
  324.         move.l  a3,d4
  325.         beq.s   SO_rts
  326.         moveq   #0,d4
  327.         bset    d7,d4   ;d4 is mask for this channel
  328.         movea.l mmd_smplarr(a2),a0
  329.         add.w   d3,d3           ;d3 = instr.num << 2
  330.         add.w   d3,d3
  331.         move.l  0(a0,d3.w),d5       ;get address of instrument
  332.     IFNE    MIDI
  333.         bne.s   inmem
  334.         tst.b   inst_midich(a3)     ;is MIDI channel set?
  335.     ENDC
  336.     IFNE    CHECK
  337.         beq.w   pnote_rts       ; NO!!!
  338.     ENDC
  339. ; -------- ADD TRANSPOSE -------------------------------------------------
  340. inmem       add.b   msng_playtransp(a4),d1  ;add play transpose
  341.         add.b   inst_strans(a3),d1  ;and instr. transpose
  342. ; -------- TURN OFF CHANNEL DMA, IF REQUIRED -----------------------------
  343.         cmp.b   #4,d7
  344.         bge.s   nodmaoff    ;track # >= 4: not an Amiga channel
  345.         move.l  d5,a1
  346.     IFNE    SYNTH
  347.         tst.l   d5
  348.         beq.s   stpdma
  349.         tst.b   trk_synthtype(a5)
  350.         ble.s   stpdma      ;prev. type = sample/hybrid
  351.         cmp.w   #-1,4(a1)   ;type == SYNTHETIC??
  352.         beq.s   nostpdma
  353.     ENDC
  354. stpdma:     move.w  d4,$dff096      ;stop this channel (dmacon)
  355. nostpdma:
  356.     IFNE    SYNTH
  357.         clr.l   trk_synthptr(a5)
  358.     ENDC
  359. nodmaoff:   subq.b  #1,d1
  360.     IFNE    MIDI
  361. ; -------- KILL PREVIOUS MIDI NOTE ---------------------------------------
  362.         move.b  trk_prevmidin(a5),d3    ;get prev. midi note
  363.         beq.s   noprevmidi
  364.         clr.b   trk_prevmidin(a5)
  365.         lea noteondata+2-DB(a6),a0
  366.         clr.b   (a0)
  367.         move.b  d3,-(a0)
  368.         bmi.s   noprevmidi
  369.         move.b  trk_prevmidich(a5),-(a0) ;prev midi channel
  370.         or.b    #$90,(a0)        ;note off
  371.         move.w  d1,-(sp)
  372.         moveq   #3,d0
  373.         bsr.w   _AddMIDId
  374.         move.w  (sp)+,d1
  375. noprevmidi:
  376. ; -------- IF MIDI NOTE, CALL MIDI NOTE ROUTINE --------------------------
  377.         tst.b   inst_midich(a3)
  378.         bne.w   handleMIDInote
  379.     ENDC
  380. ; -------- SET SOME AMIGA-CHANNEL PARAMETERS -----------------------------
  381.     IFNE    CHECK
  382.         cmp.w   #4,d7       ;track > 3???
  383.         bge.w   pnote_rts   ;no Amiga instruments here!!!
  384.     ENDC
  385. ; handle decay (for tracks 0 - 3 only!!)
  386.     IFNE    HOLD
  387.         clr.b   trk_fadespd(a5)     ;no fade yet..
  388.         move.b  trk_initdecay(a5),trk_decay(a5) ;set decay
  389.     ENDC
  390.         clr.w   trk_vibroffs(a5)    ;clr vibrato/tremolo offset
  391.         or.w    d4,dmaonmsk-DB(a6)
  392.         move.l  d5,a0
  393.     IFNE    SYNTH
  394. ; -------- IF SYNTH NOTE, CALL SYNTH ROUTINE -----------------------------
  395.         tst.w   4(a0)
  396.         bmi.w   handleSynthnote
  397.         clr.b   trk_synthtype(a5)
  398.     ENDC
  399. ; -------- CHECK NOTE RANGE ----------------------------------------------
  400. tlwtst0     tst.b   d1
  401.         bpl.s   notenot2low
  402.         add.b   #12,d1  ;note was too low, octave up
  403.         bra.s   tlwtst0
  404. notenot2low cmp.b   #62,d1
  405.         ble.s   endpttest
  406.         sub.b   #12,d1  ;note was too high, octave down
  407. endpttest
  408.         moveq   #0,d2
  409.         moveq   #0,d3
  410.         lea _periodtable+32-DB(a6),a1
  411.         move.b  trk_finetune(a5),d2 ;finetune value
  412.         add.b   d2,d2
  413.         add.b   d2,d2       ;multiply by 4...
  414.         ext.w   d2      ;extend
  415.         movea.l 0(a1,d2.w),a1   ;period table address
  416.     IFNE    IFFMOCT
  417.         move.w  4(a0),d0    ;Soitin-struct in a0
  418.         bne.s   gid_notnormal   ;note # in d1 (0 - ...)
  419.     ENDC
  420. gid_cont_ext    move.l  a1,trk_periodtbl(a5)
  421.         add.b   d1,d1
  422.         move.w  0(a1,d1.w),d5 ;put period to d5
  423.         move.l  a0,d0
  424.         addq.l  #6,d0       ;Skip structure
  425.         move.l  (a0),d1     ;length
  426.         add.l   d0,d1       ;sample end pointer
  427.         move.w  inst_repeat(a3),d2
  428.         move.w  inst_replen(a3),d3
  429.     IFNE    IFFMOCT
  430.         bra gid_setrept
  431. gid_addtable    dc.b    0,6,12,18,24,30
  432. gid_divtable    dc.b    31,7,3,15,63,127
  433. gid_notnormal   cmp.w   #7,d0
  434.         blt.s   gid_not_ext
  435.         suba.w  #48,a1
  436.         bra.s   gid_cont_ext
  437. gid_not_ext move.l  d7,-(sp)
  438.         moveq   #0,d7
  439.         move.w  d1,d7
  440.         divu    #12,d7  ;octave #
  441.         move.l  d7,d5
  442.         cmp.w   #6,d7   ;if oct > 5, oct = 5
  443.         blt.s   nohioct
  444.         moveq   #5,d7
  445. nohioct     swap    d5  ;note number in this oct (0-11) is in d5
  446.         move.l  (a0),d1
  447.         cmp.w   #6,d0
  448.         ble.s   nounrecit
  449.         moveq   #6,d0
  450. nounrecit   add.b   gid_addtable-1(pc,d0.w),d7
  451.         move.b  gid_divtable-1(pc,d0.w),d0
  452.         divu    d0,d1   ;get length of the highest octave
  453.         swap    d1
  454.         clr.w   d1
  455.         swap    d1
  456.         move.l  d1,d0       ;d0 and d1 = length of the 1st oct
  457.         move.w  inst_repeat(a3),d2
  458.         move.w  inst_replen(a3),d3
  459.         moveq   #0,d6
  460.         move.b  shiftcnt(pc,d7.w),d6
  461.         lsl.w   d6,d2
  462.         lsl.w   d6,d3
  463.         lsl.w   d6,d1
  464.         move.b  mullencnt(pc,d7.w),d6
  465.         mulu    d6,d0       ;offset of this oct from 1st oct
  466.         add.l   a0,d0       ;add base address to offset
  467.         addq.l  #6,d0       ;skip structure
  468.         add.l   d0,d1
  469.         move.l  a1,trk_periodtbl(a5)
  470.         add.b   octstart(pc,d7.w),d5
  471.         add.b   d5,d5
  472.         move.w  0(a1,d5.w),d5
  473.         move.l  (sp)+,d7
  474.         bra.s   gid_setrept
  475. shiftcnt:   dc.b    4,3,2,1,1,0,2,2,1,1,0,0,1,1,0,0,0,0
  476.         dc.b    3,3,2,2,1,0,5,4,3,2,1,0,6,5,4,3,2,1
  477. mullencnt:  dc.b    15,7,3,1,1,0,3,3,1,1,0,0,1,1,0,0,0,0
  478.         dc.b    7,7,3,3,1,0,31,15,7,3,1,0,63,31,15,7,3,1
  479. octstart:   dc.b    12,12,12,12,24,24,0,12,12,24,24,36,0,12,12,24,36,36
  480.         dc.b    0,12,12,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12
  481.     ENDC
  482. gid_setrept add.l   d2,d2
  483.         add.l   d0,d2       ;rep. start pointer
  484.         cmp.w   #1,d3
  485.         bhi.s   gid_noreplen2
  486.         moveq   #0,d3       ;no repeat
  487.         bra.s   gid_cont
  488. gid_noreplen2   add.l   d3,d3
  489.         add.l   d2,d3       ;rep. end pointer
  490.  
  491. ; -------- CALCULATE START/END ADDRESSES ---------------------------------
  492. gid_cont    moveq   #0,d4
  493.         move.w  trk_soffset(a5),d4
  494.         add.l   d4,d0
  495.         cmp.l   d0,d1
  496.         bhi.s   pn_nooffsovf
  497.         sub.l   d4,d0
  498. pn_nooffsovf    movea.l trk_audioaddr(a5),a1 ;base of this channel's regs
  499.         move.l  d0,(a1)+        ;push ac_ptr
  500.         moveq   #0,d4
  501.         move.b  trk_previnstr(a5),d4
  502.         lea flags-DB(a6),a0
  503.         btst    #0,0(a0,d4.w)       ;test flags.SSFLG_LOOP
  504.         bne.s   repeat
  505.         
  506.         move.l  #_chipzero,trk_sampleptr(a5) ;pointer of zero word
  507.         move.w  #1,trk_samplelen(a5)    ;length: 1 word
  508.         sub.l   d0,d1
  509.         lsr.l   #1,d1           ;shift length right
  510.         move.w  d1,(a1)+        ;and push to ac_len
  511.         bra.s   retsn1
  512.  
  513. repeat      move.l  d2,trk_sampleptr(a5)
  514.         move.l  d3,d1
  515.         sub.l   d0,d1
  516.         lsr.l   #1,d1
  517.         move.w  d1,(a1)+    ;ac_len
  518.         sub.l   d2,d3
  519.         lsr.l   #1,d3
  520.         move.w  d3,trk_samplelen(a5)
  521.                 
  522. retsn1      move.w  d5,trk_prevper(a5)
  523.     IFNE    SYNTH
  524.         tst.b   trk_synthtype(a5)
  525.         bne.w   hSn2
  526.     ENDC
  527. pnote_rts   rts
  528.  
  529.     IFNE    MIDI
  530. ; -------- MIDI NOTE PLAYER ROUTINE --------------------------------------
  531. handleMIDInote:
  532.     IFNE    PLAYMMD0
  533.         cmp.b   #'1',3(a2)
  534.         bge.s   plr_mmd1_3
  535.         add.b   #24,d1
  536. plr_mmd1_3
  537.     ENDC
  538. ; -------- CHECK & SCALE VOLUME ------------------------------------------
  539.         move.b  trk_prevvol(a5),d2 ;temporarily save the volume
  540.         add.b   d2,d2       ;volume 0 - 63 => 0 - 127
  541.         subq.b  #1,d2       ;if 128 => 127
  542.         bpl.s   hmn_notvolu0
  543.         moveq   #0,d2
  544. hmn_notvolu0
  545.         moveq   #0,d5
  546. ; -------- CHECK MIDI CHANNEL --------------------------------------------
  547.         move.b  inst_midich(a3),d5 ;get midi chan of this instrument
  548.         bpl.s   hmn_nosmof  ;bit 7 clear
  549.         clr.b   trk_prevmidin(a5)   ;suppress note off!
  550.         bra.s   hmn_smof
  551. hmn_nosmof  move.b  d1,trk_prevmidin(a5)
  552. hmn_smof    and.b   #$1F,d5     ;clear all flag bits etc...
  553.         subq.b  #1,d5       ;from 1-16 to 0-15
  554.         move.b  d5,trk_prevmidich(a5)   ;save to prev midi channel
  555.  
  556. ; -------- CHECK MIDI PRESET ---------------------------------------------
  557.         moveq   #0,d0
  558.         move.b  trk_previnstr(a5),d0
  559.         add.w   d0,d0
  560.         lea ext_midipsets-DB(a6),a1
  561.         move.w  0(a1,d0.w),d0   ;get preset #
  562.         beq.s   nochgpres   ;zero = no preset
  563.         lea prevmidicpres-DB(a6),a1
  564.         adda.w  d5,a1
  565.         adda.w  d5,a1
  566.         cmp.w   (a1),d0     ;is this previous preset ??
  567.         beq.s   nochgpres   ;yes...no need to change
  568.         move.w  d0,(a1)     ;save preset to prevmidicpres
  569.         subq.w  #1,d0       ;sub 1 to get 0 - 127
  570.         btst    #6,inst_midich(a3)
  571.         bne.s   hmn_extpreset
  572. ; -------- PREPARE PRESET CHANGE COMMAND ---------------------------------
  573. hmn_ordpreset   lea preschgdata+1-DB(a6),a0
  574.         move.b  d0,(a0)     ;push the number to second byte
  575.         moveq   #2,d0
  576. hmn_sendpreset  move.b  #$c0,-(a0)  ;command: $C
  577.         or.b    d5,(a0)     ;"or" midi channel
  578.         move.w  d1,-(sp)
  579.         bsr.w   _AddMIDId
  580.         move.w  (sp)+,d1
  581.         tst.b   d2
  582.         beq.s   hmn_suppress    ;vol = 0, don't send NOTE ON
  583.  
  584. ; -------- PREPARE & SEND NOTE ON COMMAND --------------------------------
  585. nochgpres   lea bytesinnotebuff-DB(a6),a0
  586.         movea.l a0,a1
  587.         adda.w  (a0)+,a0
  588.         or.b    #$90,d5     ;MIDI: Note on
  589.         move.b  d5,(a0)+    ;MIDI msg Note on & channel
  590.         move.b  d1,(a0)+    ;MIDI msg note #
  591.         move.b  d2,(a0)     ;MIDI msg volume
  592.         beq.s   hmn_suppress    ;vol = 0 -> no note
  593.         addq.w  #3,(a1)
  594.         rts
  595. hmn_suppress    st  trk_prevmidin(a5)
  596.         rts
  597.  
  598. ; -------- HANDLE EXTENDED PRESET ----------------------------------------
  599. hmn_extpreset   cmp.w   #100,d0
  600.         blt.s   hmn_ordpreset
  601.         moveq   #99,d3
  602. hmn_loop100 sub.w   #100,d0
  603.         addq.b  #1,d3
  604.         cmp.w   #100,d0
  605.         bge.s   hmn_loop100
  606.         lea preschgdata+2-DB(a6),a0
  607.         move.b  d0,(a0)     ;push the <= 99 number
  608.         move.b  d3,-(a0)    ;push the >= 100 number
  609.         moveq   #3,d0
  610.         bra.s   hmn_sendpreset
  611.     ENDC
  612.  
  613.     IFNE    SYNTH
  614. ; -------- TRIGGER SYNTH NOTE, CLEAR PARAMETERS --------------------------
  615. handleSynthnote move.b  d1,trk_prevnote2(a5)
  616.         move.l  a0,trk_synthptr(a5)
  617.         cmp.w   #-2,4(a0)   ;HYBRID??
  618.         bne.s   hSn_nossn
  619.         st  trk_synthtype(a5)
  620.         movea.l 278(a0),a0  ;yep, get the waveform pointer
  621.         bra.w   tlwtst0     ;go and play it
  622. hSn_nossn:  move.b  #1,trk_synthtype(a5)
  623.         lea _periodtable+32-DB(a6),a1
  624.         move.b  trk_finetune(a5),d0 ;finetune value
  625.         add.b   d0,d0
  626.         add.b   d0,d0       ;multiple by 4...
  627.         ext.w   d0      ;extend
  628.         movea.l 0(a1,d0.w),a1   ;period table address
  629.         suba.w  #48,a1
  630.         move.l  a1,trk_periodtbl(a5) ;save table ptr for synth periods
  631.         add.w   d1,d1
  632.         move.w  0(a1,d1.w),d1
  633.         move.w  d1,trk_prevper(a5)
  634.         clr.l   trk_sampleptr(a5)
  635. hSn2:       lea trk_arpgoffs(a5),a1
  636.         clr.l   (a1)+
  637.         clr.l   (a1)+
  638.         clr.l   (a1)+
  639.         clr.l   (a1)+
  640.         clr.l   (a1)+
  641.         clr.l   (a1)+
  642.         move.l  #sinetable,(a1)+
  643.         clr.w   (a1)+
  644.         movea.l trk_synthptr(a5),a0
  645.                 move.w  18(a0),(a1)+
  646.                 clr.b   (a1)
  647.                 cmp.b   #$E,trk_cmd(a5)
  648.                 bne.s   hSn_nocmdE
  649.                 move.b  trk_cmdqual(a5),trk_wfcmd+1(a5)
  650. hSn_nocmdE  moveq   #64,d4
  651.         rts
  652.  
  653. synth_start move.w  trk_prevper(a5),d5
  654. synth_start2    move.l  a3,-(sp)    ;d0 = SynthPtr
  655.         move.l  d0,a0
  656.         movea.l trk_audioaddr(a5),a3    ;audio channel base address
  657. ; -------- SYNTHSOUND VOLUME SEQUENCE HANDLING ---------------------------
  658.         subq.b  #1,trk_volxcnt(a5)  ;decrease execute counter..
  659.         bgt.w   synth_wftbl     ;not 0...go to waveform
  660.         move.b  trk_initvolxspd(a5),trk_volxcnt(a5) ;reset counter
  661.         move.b  trk_volchgspd(a5),d0    ;volume change??
  662.         beq.s   synth_nochgvol      ;no.
  663.         add.b   trk_synvol(a5),d0   ;add previous volume
  664.         bpl.s   synth_voln2l        ;not negative
  665.         moveq   #0,d0           ;was negative => 0
  666. synth_voln2l    cmp.b   #$40,d0         ;too high??
  667.         ble.s   synth_voln2h        ;not 2 high.
  668.         moveq   #$40,d0         ;was 2 high => 64
  669. synth_voln2h    move.b  d0,trk_synvol(a5)   ;remember new...
  670. synth_nochgvol  move.l  trk_envptr(a5),d1   ;envelope pointer
  671.         beq.s   synth_novolenv
  672.         movea.l d1,a1
  673.         move.b  (a1)+,d0
  674.         add.b   #128,d0
  675.         lsr.b   #2,d0
  676.         move.b  d0,trk_synvol(a5)
  677.         addq.b  #1,trk_envcount(a5)
  678.         bpl.s   synth_endenv
  679.         clr.b   trk_envcount(a5)
  680.         move.l  trk_envrestart(a5),a1
  681. synth_endenv    move.l  a1,trk_envptr(a5)
  682. synth_novolenv  move.w  trk_volcmd(a5),d0   ;get table position ptr
  683.         tst.b   trk_volwait(a5)     ;WAI(t) active
  684.         beq.s   synth_getvolcmd     ;no
  685.         subq.b  #1,trk_volwait(a5)  ;yep, decr wait ctr
  686.         ble.s   synth_getvolcmd     ;0 => continue
  687.         bra.w   synth_wftbl     ;> 0 => still wait
  688. synth_inccnt    addq.b  #1,d0
  689. synth_getvolcmd addq.b  #1,d0           ;advance pointer
  690.         move.b  21(a0,d0.w),d1      ;get command
  691.         bmi.s   synth_cmd       ;negative = command
  692.         move.b  d1,trk_synvol(a5)   ;set synthvol
  693.         bra.w   synth_endvol        ;end of volume executing
  694. synth_cmd   and.w   #$000f,d1
  695.         add.b   d1,d1
  696.         move.w  synth_vtbl(pc,d1.w),d1
  697.         jmp syv(pc,d1.w)
  698. synth_vtbl  dc.w    syv_f0-syv,syv_f1-syv,syv_f2-syv,syv_f3-syv
  699.         dc.w    syv_f4-syv,syv_f5-syv,syv_f6-syv
  700.         dc.w    synth_endvol-syv,synth_endvol-syv,synth_endvol-syv
  701.         dc.w    syv_fa-syv,syv_ff-syv,synth_endvol-syv
  702.         dc.w    synth_endvol-syv,syv_fe-syv,syv_ff-syv
  703. ; -------- VOLUME SEQUENCE COMMANDS --------------------------------------
  704. syv
  705. syv_fe      move.b  22(a0,d0.w),d0      ;JMP
  706.         bra.s   synth_getvolcmd
  707. syv_f0      move.b  22(a0,d0.w),trk_initvolxspd(a5) ;change volume ex. speed
  708.         bra.s   synth_inccnt
  709. syv_f1      move.b  22(a0,d0.w),trk_volwait(a5) ;WAI(t)
  710.         addq.b  #1,d0
  711.         bra.s   synth_endvol
  712. syv_f3      move.b  22(a0,d0.w),trk_volchgspd(a5) ;set volume slide up
  713.         bra.s   synth_inccnt
  714. syv_f2      move.b  22(a0,d0.w),d1
  715.         neg.b   d1
  716.         move.b  d1,trk_volchgspd(a5) ;set volume slide down
  717.         bra.s   synth_inccnt
  718. syv_fa      move.b  22(a0,d0.w),trk_wfcmd+1(a5) ;JWS (jump wform sequence)
  719.         clr.b   trk_wfwait(a5)
  720.         bra.s   synth_inccnt
  721. syv_f4      move.b  22(a0,d0.w),d1
  722.         bsr.s   synth_getwf
  723.         clr.l   trk_envrestart(a5)
  724. syv_f4end   move.l  a1,trk_envptr(a5)
  725.         clr.b   trk_envcount(a5)
  726.         bra.w   synth_inccnt
  727. syv_f5      move.b  22(a0,d0.w),d1
  728.         bsr.s   synth_getwf
  729.         move.l  a1,trk_envrestart(a5)
  730.         bra.s   syv_f4end
  731. syv_f6      clr.l   trk_envptr(a5)
  732.         bra.w   synth_getvolcmd
  733. synth_getwf ext.w   d1  ;d1 = wform number, returns ptr in a1
  734.         add.w   d1,d1   ;create index
  735.         add.w   d1,d1
  736.         lea 278(a0),a1
  737.         adda.w  d1,a1
  738.         movea.l (a1),a1     ;get wform address
  739.         addq.l  #2,a1       ;skip length
  740.         rts
  741. syv_ff      subq.b  #1,d0
  742. synth_endvol    move.w  d0,trk_volcmd(a5)
  743. synth_wftbl
  744.     IFNE    RELVOL
  745.         moveq   #0,d0
  746.         move.b  trk_synvol(a5),d0
  747.         mulu    trk_trackvol(a5),d0
  748.         lsr.w   #8,d0
  749.         move.b  d0,trk_prevvol(a5) ;vol of this instr
  750.     ENDC
  751.     IFEQ    RELVOL
  752.         move.b  trk_synvol(a5),trk_prevvol(a5)
  753.     ENDC
  754.         adda.w  #158,a0
  755. ; -------- SYNTHSOUND WAVEFORM SEQUENCE HANDLING -------------------------
  756.         subq.b  #1,trk_wfxcnt(a5)   ;decr. wf speed counter
  757.         bgt.w   synth_arpeggio      ;not yet...
  758.         move.b  trk_initwfxspd(a5),trk_wfxcnt(a5) ;restore speed counter
  759.         move.w  trk_wfcmd(a5),d0    ;get table pos offset
  760.         move.w  trk_wfchgspd(a5),d1 ;CHU/CHD ??
  761.         beq.s   synth_tstwfwai      ;0 = no change
  762. wytanwet    add.w   trk_perchg(a5),d1   ;add value to current change
  763.         move.w  d1,trk_perchg(a5)   ;remember amount of change
  764. synth_tstwfwai  tst.b   trk_wfwait(a5)      ;WAI ??
  765.         beq.s   synth_getwfcmd      ;not waiting...
  766.         subq.b  #1,trk_wfwait(a5)   ;decr wait counter
  767.         beq.s   synth_getwfcmd      ;waiting finished
  768.         bra.w   synth_arpeggio      ;still sleep...
  769. synth_incwfc    addq.b  #1,d0
  770. synth_getwfcmd  addq.b  #1,d0           ;advance position counter
  771.         move.b  -9(a0,d0.w),d1      ;get command
  772.         bmi.s   synth_wfcmd     ;negative = command
  773.         ext.w   d1
  774.         add.w   d1,d1
  775.         add.w   d1,d1
  776.         movea.l 120(a0,d1.w),a1
  777.         move.w  (a1)+,ac_len(a3)    ;push waveform length
  778.         move.l  a1,ac_ptr(a3)       ;and the new pointer
  779.         bra.w   synth_wfend     ;no new commands now...
  780. synth_wfcmd and.w   #$000f,d1       ;get the right nibble
  781.         add.b   d1,d1           ;* 2
  782.         move.w  synth_wfctbl(pc,d1.w),d1
  783.         jmp syw(pc,d1.w)        ;jump to command
  784. synth_wfctbl    dc.w    syw_f0-syw,syw_f1-syw,syw_f2-syw,syw_f3-syw,syw_f4-syw
  785.         dc.w    syw_f5-syw,syw_f6-syw,syw_f7-syw,synth_wfend-syw
  786.         dc.w    synth_wfend-syw,syw_fa-syw,syw_ff-syw
  787.         dc.w    syw_fc-syw,synth_getwfcmd-syw,syw_fe-syw,syw_ff-syw
  788. ; -------- WAVEFORM SEQUENCE COMMANDS ------------------------------------
  789. syw
  790. syw_f7      move.b  -8(a0,d0.w),d1
  791.         ext.w   d1
  792.         add.w   d1,d1
  793.         add.w   d1,d1
  794.         movea.l 120(a0,d1.w),a1
  795.         addq.l  #2,a1
  796.         move.l  a1,trk_synvibwf(a5)
  797.         bra.s   synth_incwfc
  798. syw_fe      move.b  -8(a0,d0.w),d0      ;jump (JMP)
  799.         bra.s   synth_getwfcmd
  800. syw_fc      move.w  d0,trk_arpsoffs(a5) ;new arpeggio begin
  801.         move.w  d0,trk_arpgoffs(a5)
  802. synth_findare   addq.b  #1,d0
  803.         tst.b   -9(a0,d0.w)
  804.         bpl.s   synth_findare
  805.         bra.s   synth_getwfcmd
  806. syw_f0      move.b  -8(a0,d0.w),trk_initwfxspd(a5)  ;new waveform speed
  807.         bra synth_incwfc
  808. syw_f1      move.b  -8(a0,d0.w),trk_wfwait(a5)  ;wait waveform
  809.         addq.b  #1,d0
  810.         bra.s   synth_wfend
  811. syw_f4      move.b  -8(a0,d0.w),trk_synvibdep+1(a5) ;set vibrato depth
  812.         bra.w   synth_incwfc
  813. syw_f5      move.b  -8(a0,d0.w),trk_synthvibspd+1(a5) ;set vibrato speed
  814.         addq.b  #1,trk_synthvibspd+1(a5)
  815.         bra.w   synth_incwfc
  816. syw_f2      moveq   #0,d1           ;set slide down
  817.         move.b  -8(a0,d0.w),d1
  818. synth_setsld    move.w  d1,trk_wfchgspd(a5)
  819.         bra.w   synth_incwfc
  820. syw_f3      move.b  -8(a0,d0.w),d1      ;set slide up
  821.         neg.b   d1
  822.         ext.w   d1
  823.         bra.s   synth_setsld
  824. syw_f6      clr.w   trk_perchg(a5)      ;reset period
  825.         move.w  trk_prevper(a5),d5
  826.         bra.w   synth_getwfcmd
  827. syw_fa      move.b  -8(a0,d0.w),trk_volcmd+1(a5) ;JVS (jump volume sequence)
  828.         clr.b   trk_volwait(a5)
  829.         bra.w   synth_incwfc
  830. syw_ff      subq.b  #1,d0       ;pointer = END - 1
  831. synth_wfend move.w  d0,trk_wfcmd(a5)
  832. ; -------- HANDLE SYNTHSOUND ARPEGGIO ------------------------------------
  833. synth_arpeggio  move.w  trk_arpgoffs(a5),d0
  834.         beq.s   synth_vibrato
  835.         moveq   #0,d1
  836.         move.b  -8(a0,d0.w),d1
  837.         add.b   trk_prevnote2(a5),d1
  838.         movea.l trk_periodtbl(a5),a1    ;get period table
  839.         add.w   d1,d1
  840.         move.w  0(a1,d1.w),d5
  841.         addq.b  #1,d0
  842.         tst.b   -8(a0,d0.w)
  843.         bpl.s   synth_noarpres
  844.         move.w  trk_arpsoffs(a5),d0
  845. synth_noarpres  move.w  d0,trk_arpgoffs(a5)
  846. ; -------- HANDLE SYNTHSOUND VIBRATO -------------------------------------
  847. synth_vibrato   move.w  trk_synvibdep(a5),d1    ;get vibrato depth
  848.         beq.s   synth_rts       ;0 => no vibrato
  849.         move.w  trk_synviboffs(a5),d0   ;get offset
  850.         lsr.w   #4,d0           ;/ 16
  851.         and.w   #$1f,d0         ;sinetable offset (0-31)
  852.         movea.l trk_synvibwf(a5),a0
  853.         move.b  0(a0,d0.w),d0       ;get a byte
  854.         ext.w   d0          ;to word
  855.         muls    d1,d0           ;amplify (* depth)
  856.         asr.w   #8,d0           ;and divide by 64
  857.         add.w   d0,d5           ;add vibrato...
  858.         move.w  trk_synthvibspd(a5),d0  ;vibrato speed
  859.         add.w   d0,trk_synviboffs(a5)   ;add to offset
  860. synth_rts   add.w   trk_perchg(a5),d5
  861.         cmp.w   #113,d5         ;overflow??
  862.         bge.s   synth_pern2h
  863.         moveq   #113,d1
  864. synth_pern2h    move.l  (sp)+,a3
  865.         rts
  866.     ENDC
  867. sinetable   dc.b    0,25,49,71,90,106,117,125,127,125,117,106,90,71,49
  868.         dc.b    25,0,-25,-49,-71,-90,-106,-117,-125,-127,-125,-117
  869.         dc.b    -106,-90,-71,-49,-25,0
  870.  
  871. _IntHandler:    movem.l d2-d7/a2-a6,-(sp)
  872.     IFNE    CIAB|VBLANK
  873.         movea.l a1,a6   ;get data base address (int_Data)
  874.     ENDC
  875.     IFEQ    CIAB|VBLANK
  876.         lea DB,a6   ;don't expect a1 to contain DB address
  877.     ENDC
  878.         tst.b   bpmcounter-DB(a6)
  879.         bmi.s   plr_nobpm
  880.         subq.b  #1,bpmcounter-DB(a6)
  881.         ble.s   plr_bpmcnt0
  882.         bra.w   plr_exit
  883. plr_bpmcnt0 move.b  #4,bpmcounter-DB(a6)
  884. plr_nobpm   movea.l _module-DB(a6),a2
  885.         move.l  a2,d0
  886.         beq.w   plr_exit
  887.     IFNE    MIDI
  888.         clr.b   lastcmdbyte-DB(a6)  ;no MIDI optimization
  889.     ENDC
  890.         tst.w   mmd_pstate(a2)
  891.         beq.w   plr_exit
  892.     IFNE    MIDI
  893.         clr.l   dmaonmsk-DB(a6)
  894.     ENDC
  895.     IFEQ    MIDI
  896.         clr.w   dmaonmsk-DB(a6)
  897.     ENDC
  898.         movea.l mmd_songinfo(a2),a4
  899.         moveq   #0,d3
  900.         move.b  mmd_counter(a2),d3
  901.         addq.b  #1,d3
  902.         cmp.b   msng_tempo2(a4),d3
  903.         bge.s   plr_pnewnote    ;play new note
  904.         move.b  d3,mmd_counter(a2)
  905.         bne.w   plr_fxtime  ;do just fx
  906. ; --- new note!!
  907. plr_pnewnote:   clr.b   mmd_counter(a2)
  908.         tst.w   blkdelay-DB(a6)
  909.         beq.s   plr_noblkdelay
  910.         subq.w  #1,blkdelay-DB(a6)
  911.         bne.w   nonewnote
  912. ; --- now start to play it
  913. plr_noblkdelay  move.w  mmd_pblock(a2),d0
  914.         movea.l mmd_blockarr(a2),a0
  915.         add.w   d0,d0
  916.         add.w   d0,d0
  917.         movea.l 0(a0,d0.w),a1   ;block...
  918.         move.w  mmd_pline(a2),d0
  919.     IFNE    PLAYMMD0
  920.         cmp.b   #'1',3(a2)  ;check ID type
  921.         bge.s   plr_mmd1_0
  922.         move.w  d0,d1
  923.         add.w   d0,d0
  924.         add.w   d1,d0       ;d0 = d0 * 3
  925.         clr.l   numtracks-DB(a6)
  926.         move.b  (a1)+,numtracks+1-DB(a6)
  927.         move.b  (a1),numlines+1-DB(a6)
  928.         mulu    numtracks-DB(a6),d0
  929.         pea 1(a1,d0.w)
  930.         bra.s   plr_begloop
  931. plr_mmd1_0
  932.     ENDC
  933.         add.w   d0,d0
  934.         add.w   d0,d0       ;d0 = d0 * 4
  935.         mulu    (a1),d0     ;numtracks * d0
  936.         pea 8(a1,d0.l)  ;address of the current note
  937.         move.w  (a1)+,numtracks-DB(a6)
  938.         move.w  (a1),numlines-DB(a6)
  939. plr_begloop moveq   #0,d7       ;number of track
  940.         moveq   #0,d4
  941.         pea trackdataptrs-DB(a6)
  942. plr_loop0:  moveq   #0,d5
  943.         move.l  (sp),a1
  944.         movea.l (a1)+,a5    ;get address of this track's struct
  945.         move.l  a1,(sp)
  946. ; SPECIAL...
  947.         tst.w   d7
  948.         bne.s   skipch0_0
  949.         tst.w   _freech0
  950.         bne.w   plr_endloop0
  951. skipch0_0
  952. ; END OF SPECIAL
  953. ; ---------------- get the note numbers
  954.         moveq   #0,d3
  955.         move.l  4(sp),a1
  956.     IFNE    PLAYMMD0
  957.         cmp.b   #'1',3(a2)
  958.         bge.s   plr_mmd1_1
  959.         move.b  (a1)+,d5
  960.         move.b  (a1)+,d6
  961.         move.b  (a1)+,trk_cmdqual(a5)
  962.         move.b  d6,d3
  963.         and.w   #$0F,d6
  964.         lsr.b   #4,d3
  965.         bclr    #7,d5
  966.         beq.s   plr_bseti4
  967.         bset    #4,d3
  968. plr_bseti4  bclr    #6,d5
  969.         beq.s   plr_bseti5
  970.         bset    #5,d3
  971. plr_bseti5  bra.s   plr_nngok
  972. plr_mmd1_1
  973.     ENDC
  974.         move.b  (a1)+,d5    ;get the number of this note
  975.         bpl.s   plr_nothinote
  976.         moveq   #0,d5
  977. plr_nothinote   move.b  (a1)+,d3    ;instrument number
  978.         move.b  (a1)+,d6    ;cmd number
  979.         and.w   #$1F,d6     ;recognize only cmds 00 - 1F
  980.         move.b  (a1)+,trk_cmdqual(a5)   ;databyte (qualifier)
  981. plr_nngok   move.l  a1,4(sp)
  982. ; ---------------- check if there's an instrument number
  983.         and.w   #$3F,d3
  984.         beq.s   noinstnum
  985. ; ---------------- finally, save the number
  986.         subq.b  #1,d3
  987.         move.b  d3,trk_previnstr(a5) ;remember instr. number!
  988.     IFNE    HOLD
  989.         lea holdvals-DB(a6),a0
  990.         adda.w  d3,a0
  991.         move.b  (a0),trk_inithold(a5)
  992.         move.b  63(a0),trk_initdecay(a5)
  993.         move.b  126(a0),trk_finetune(a5)
  994.     ENDC
  995.     IFEQ    HOLD
  996.         lea finetunes-DB(a6),a0
  997.         move.b  0(a0,d3.w),trk_finetune(a5)
  998.     ENDC
  999.         asl.w   #3,d3
  1000.         lea 0(a4,d3.w),a3   ;a3 contains now address of it
  1001.         move.l  a3,trk_previnstra(a5)
  1002.         moveq   #0,d0
  1003. ; ---------------- get volume and make it relative (1 - 100 %)
  1004.     IFNE    RELVOL
  1005.         move.b  inst_svol(a3),d0
  1006.         mulu    trk_trackvol(a5),d0
  1007.         lsr.w   #8,d0
  1008.         move.b  d0,trk_prevvol(a5) ;vol of this instr
  1009.     ENDC
  1010.     IFEQ    RELVOL
  1011.         move.b  inst_svol(a3),trk_prevvol(a5)
  1012.     ENDC
  1013. ; ---------------- remember transpose
  1014.         move.b  inst_strans(a3),trk_stransp(a5)
  1015.         clr.w   trk_soffset(a5)     ;sample offset
  1016. ; ---------------- check the commands
  1017. noinstnum   move.b  d6,trk_cmd(a5)  ;save the effect number
  1018.         beq.w   fx  ;no effect
  1019.         move.b  trk_cmdqual(a5),d4  ;get qualifier...
  1020.         add.b   d6,d6   ;* 2
  1021.         move.w  f_table(pc,d6.w),d0
  1022.         jmp fst(pc,d0.w)
  1023. f_table     dc.w    fx-fst,fx-fst,fx-fst,f_03-fst,fx-fst,fx-fst,fx-fst,fx-fst
  1024.         dc.w    f_08-fst,f_09-fst,fx-fst,f_0b-fst,f_0c-fst,fx-fst,f_0e-fst,f_0f-fst
  1025.         dc.w    fx-fst,fx-fst,fx-fst,fx-fst,fx-fst,f_15-fst,f_16-fst,fx-fst
  1026.         dc.w    fx-fst,f_19-fst,fx-fst,fx-fst,f_1c-fst,f_1d-fst,fx-fst,f_1f-fst
  1027. fst
  1028. ; ---------------- tempo (F)
  1029. f_0f        tst.b   d4      ;test effect qual..
  1030.         beq fx0fchgblck ;if effect qualifier (last 2 #'s)..
  1031.         cmp.b   #$f0,d4     ;..is zero, go to next block
  1032.         bhi.s   fx0fspecial ;if it's F1-FF something special
  1033. ; ---------------- just an ordinary "change tempo"-request
  1034.     IFNE    CIAB
  1035.         moveq   #0,d0       ;will happen!!!
  1036.         move.b  d4,d0
  1037.         move.w  d0,msng_deftempo(a4)
  1038.         bsr _SetTempo   ;change The Tempo
  1039.     ENDC
  1040.         bra.w   fx
  1041. ; ---------------- no, it was FFx, something special will happen!!
  1042. fx0fspecial:    cmp.b   #$f2,d4
  1043.         beq.s   f_1f
  1044.         cmp.b   #$f4,d4
  1045.         beq.s   f_1f
  1046.         cmp.b   #$f5,d4
  1047.         bne.s   isfxfe
  1048. ; ---------------- FF2 (or 1Fxx)
  1049. f_1f        move.b  d5,(a5) ; save the note number
  1050.         moveq   #0,d5   ; clear the number for awhile
  1051.     IFNE    HOLD
  1052.         move.b  trk_inithold(a5),trk_noteoffcnt(a5) ;initialize hold
  1053.         bne.w   plr_endloop0        ;not 0 -> OK
  1054.         st  trk_noteoffcnt(a5)  ;0 -> hold = 0xff (-1)
  1055.     ENDC
  1056.         bra.w   plr_endloop0
  1057. isfxfe:     cmp.b   #$fe,d4
  1058.         bne.s   notcmdfe
  1059. ; ---------------- it was FFE, stop playing
  1060.         clr.w   mmd_pstate(a2)
  1061.     IFNE    CIAB
  1062.         movea.l craddr-DB(a6),a0
  1063.         bclr    #0,(a0)
  1064.     ENDC
  1065.         bsr.w   SoundOff
  1066.         addq.l  #8,sp
  1067.         bra.w   plr_exit
  1068. notcmdfe:   cmp.b   #$fd,d4 ;change period
  1069.         bne.s   isfxff
  1070. ; ---------------- FFD, change the period, don't replay the note
  1071.     IFNE    CHECK
  1072.         cmp.w   #4,d7
  1073.         bge.w   fx
  1074.     ENDC
  1075.         movea.l trk_periodtbl(a5),a0
  1076.         subq.b  #1,d5
  1077.         bmi.w   plr_endloop0
  1078.         add.b   msng_playtransp(a4),d5
  1079.         add.b   trk_stransp(a5),d5
  1080.         add.w   d5,d5
  1081.         bmi plr_endloop0
  1082.         move.w  0(a0,d5.w),trk_prevper(a5)
  1083.         moveq   #0,d5
  1084.         bra.w   fx
  1085. isfxff:     cmp.b   #$ff,d4
  1086.         bne.w   fx
  1087.         move.w  d7,d0
  1088.         bsr.w   _ChannelOff
  1089.         bra.w   fx
  1090. ; ---------------- F00, called Pattern Break in ST
  1091. fx0fchgblck:    move.b  #1,nextblock-DB(a6)
  1092.         bra.w   fx
  1093. ; ---------------- was not Fxx
  1094. f_0e        cmp.b   #3,d7
  1095.         bgt.w   fx
  1096.         move.b  d4,trk_wfcmd+1(a5) ;set waveform command position ptr
  1097.         bra.w   fx
  1098. ; ---------------- change volume
  1099. f_0c        move.b  d4,d0
  1100.         bpl.s   plr_nosetdefvol
  1101.         and.b   #$7F,d0
  1102.     IFNE    CHECK
  1103.         cmp.b   #64,d0
  1104.         bgt.s   go_nocmd
  1105.     ENDC
  1106.         moveq   #0,d1
  1107.         move.b  trk_previnstr(a5),d1
  1108.         asl.w   #3,d1
  1109.         move.b  d0,inst_svol(a4,d1.w)
  1110.         bra.s   plr_setvol
  1111. plr_nosetdefvol btst    #4,msng_flags(a4)   ;look at flags
  1112.         bne.s   volhex
  1113.         lsr.b   #4,d0       ;get number from left
  1114.         mulu    #10,d0      ;number of tens
  1115.         move.b  d4,d1       ;get again
  1116.         and.b   #$0f,d1     ;this time don't get tens
  1117.         add.b   d1,d0       ;add them
  1118. volhex:
  1119.     IFNE    CHECK
  1120.         cmp.b   #64,d0
  1121.         bhi.s   go_nocmd
  1122.     ENDC
  1123. plr_setvol
  1124.     IFNE    RELVOL
  1125.         mulu    trk_trackvol(a5),d0
  1126.         lsr.w   #8,d0
  1127.     ENDC
  1128.         move.b  d0,trk_prevvol(a5)
  1129. go_nocmd    bra.w   fx
  1130. ; ---------------- tempo2 change?
  1131. f_09
  1132.     IFNE    CHECK
  1133.         and.b   #$1F,d4
  1134.         bne.s   fx9chk
  1135.         moveq   #$20,d4
  1136.     ENDC
  1137. fx9chk:     move.b  d4,msng_tempo2(a4)
  1138.         bra fx
  1139. ; ---------------- finetune
  1140. f_15
  1141.     IFNE    CHECK
  1142.         cmp.b   #7,d4
  1143.         bgt fx
  1144.         cmp.b   #-8,d4
  1145.         blt fx
  1146.     ENDC
  1147.         move.b  d4,trk_finetune(a5)
  1148.         bra fx
  1149. ; ---------------- repeat loop
  1150. f_16        tst.b   d4
  1151.         bne.s   plr_dorpt
  1152.         move.w  mmd_pline(a2),rptline-DB(a6)
  1153.         bra fx
  1154. plr_dorpt   tst.w   rptcounter-DB(a6)
  1155.         beq.s   plr_newrpt
  1156.         subq.w  #1,rptcounter-DB(a6)
  1157.         beq fx
  1158.         bra.s   plr_setrptline
  1159. plr_newrpt  move.b  d4,rptcounter+1-DB(a6)
  1160. plr_setrptline  move.w  rptline-DB(a6),d0
  1161.         addq.w  #1,d0
  1162.         move.w  d0,nextblockline-DB(a6)
  1163.         bra fx
  1164. ; ---------------- preset change
  1165. f_1c
  1166.     IFNE    CHECK
  1167.         cmp.b   #$80,d4
  1168.         bhi fx
  1169.     ENDC
  1170.         moveq   #0,d1
  1171.         move.b  trk_previnstr(a5),d1
  1172.         add.w   d1,d1
  1173.         lea ext_midipsets-DB(a6),a0
  1174.         ext.w   d4
  1175.         move.w  d4,0(a0,d1.w)   ;set MIDI preset
  1176.         bra.s   fx
  1177. ; ---------------- note off time set??
  1178. f_08
  1179.     IFNE    HOLD
  1180.         move.b  d4,d0
  1181.         lsr.b   #4,d4       ;extract left  nibble
  1182.         and.b   #$0f,d0     ; "   "  right  "  "
  1183.         move.b  d4,trk_initdecay(a5)    ;left = decay
  1184.         move.b  d0,trk_inithold(a5) ;right = hold
  1185.     ENDC
  1186.         bra.s   fx
  1187. ; ---------------- sample begin offset
  1188. f_19        lsl.w   #8,d4
  1189.         move.w  d4,trk_soffset(a5)
  1190.         bra.s   fx
  1191. ; ---------------- cmd Bxx, "position jump"
  1192. f_0b
  1193.     IFNE    CHECK
  1194.         cmp.b   #'2',3(a2)
  1195.         beq.s   chk0b_mmd2
  1196.         cmp.w   msng_songlen(a4),d4
  1197.         bhi.s   fx
  1198.         bra.s   chk0b_end
  1199. chk0b_mmd2  move.w  mmd_pseq(a2),d0     ;get seq number
  1200.         movea.l msng_pseqs(a4),a1   ;ptr to playseqs
  1201.         movea.l 0(a1,d0.w),a0       ;a0 = ptr to curr PlaySeq
  1202.         cmp.w   40(a0),d4       ;test song length
  1203.         bhi.s   fx
  1204. chk0b_end
  1205.     ENDC
  1206.         move.w  d4,mmd_pseqnum(a2)
  1207.         st  nextblock-DB(a6)    ; = 1
  1208.         bra.s   fx
  1209. ; ---------------- cmd 1Dxx, jump to next seq, line # specified
  1210. f_1d        move.w  #$1ff,nextblock-DB(a6)
  1211.         addq.w  #1,d4
  1212.         move.w  d4,nextblockline-DB(a6)
  1213.         bra.s   fx
  1214. ; ---------------- try portamento (3)
  1215. f_03
  1216.     IFNE    CHECK
  1217.         cmp.w   #4,d7
  1218.         bge.s   plr_endloop0
  1219.     ENDC
  1220.         subq.b  #1,d5       ;subtract note number
  1221.         bmi.s   plr_setfx3spd   ;0 -> set new speed
  1222. plr_fx3note:    movea.l trk_periodtbl(a5),a0
  1223.         add.b   msng_playtransp(a4),d5  ;play transpose
  1224.         add.b   trk_stransp(a5),d5  ;and instrument transpose
  1225.         bmi.s   plr_endloop0
  1226.         add.w   d5,d5
  1227.         move.w  0(a0,d5.w),trk_porttrgper(a5) ;period of this note is the target
  1228. plr_setfx3spd:  tst.b   d4      ;qual??
  1229.         beq.s   plr_endloop0    ;0 -> do nothing
  1230.         move.b  d4,trk_prevportspd(a5)  ;store speed
  1231.         bra.s   plr_endloop0        ;don't play this one
  1232. ; ---------------- play or not to play??
  1233. fx      tst.b   d5          ;play a note?
  1234.         beq.s   plr_endloop0        ;no.
  1235. ; ---------------- play
  1236.         move.b  d5,(a5)
  1237.         move.w  d5,d1
  1238.         moveq   #0,d3
  1239.         move.b  trk_previnstr(a5),d3    ;instr #
  1240.         movea.l trk_previnstra(a5),a3   ;instr data address
  1241.     IFNE    HOLD
  1242.         move.b  trk_inithold(a5),trk_noteoffcnt(a5) ;initialize hold
  1243.         bne.s   plr_nohold0     ;not 0 -> OK
  1244.         st  trk_noteoffcnt(a5)  ;0 -> hold = 0xff (-1)
  1245.     ENDC
  1246. ; ---------------- and finally:
  1247. plr_nohold0 bsr _PlayNote
  1248. ; ---------------- end of loop: handle next track, or quit
  1249. plr_endloop0:   addq.b  #1,d7
  1250.         cmp.w   numtracks-DB(a6),d7
  1251.         blt.w   plr_loop0
  1252.         addq.l  #8,sp           ;trackdataptrs / note ptr
  1253. ; and advance song pointers
  1254.         lea nextblock-DB(a6),a3
  1255.         move.w  nextblockline-DB(a6),d1
  1256.         beq.s   plr_advlinenum
  1257.         clr.w   nextblockline-DB(a6)
  1258.         subq.w  #1,d1
  1259.         bra.s   plr_linenumset
  1260. plr_advlinenum  move.w  mmd_pline(a2),d1    ;get current line #
  1261.         addq.w  #1,d1           ;advance line number
  1262. plr_linenumset  cmp.w   numlines-DB(a6),d1  ;advance block?
  1263.         bhi.s   plr_chgblock        ;yes.
  1264.         tst.b   (a3)            ;command F00/1Dxx?
  1265.         beq plr_nochgblock      ;no, don't change block
  1266. ; -------- CHANGE BLOCK? -------------------------------------------------
  1267. plr_chgblock    tst.b   nxtnoclrln-DB(a6)
  1268.         bne.s   plr_noclrln
  1269.         moveq   #0,d1           ;clear line number
  1270. plr_noclrln tst.w   mmd_pstate(a2)      ;play block or play song
  1271.         bpl plr_nonewseq        ;play block only...
  1272.         cmp.b   #'2',3(a2)      ;MMD2?
  1273.         bne.s   plr_noMMD2_0
  1274. ; ********* BELOW CODE FOR MMD2 ONLY ************************************
  1275. ; -------- CHANGE SEQUENCE -----------------------------------------------
  1276. plr_skipseq move.w  mmd_pseq(a2),d0     ;actually stored as << 2
  1277.         movea.l msng_pseqs(a4),a1
  1278.         movea.l 0(a1,d0.w),a0
  1279.         move.w  mmd_pseqnum(a2),d0  ;get play sequence number
  1280.         tst.b   (a3)
  1281.         bmi.s   plr_noadvseq        ;Bxx sets nextblock to -1
  1282.         addq.w  #1,d0           ;advance sequence number
  1283. plr_noadvseq    cmp.w   40(a0),d0       ;is this the highest seq number??
  1284.         blt.s   plr_notagain        ;no.
  1285. ; -------- CHANGE SECTION ------------------------------------------------
  1286.         move.w  mmd_psecnum(a2),d0  ;get section number
  1287.         addq.w  #1,d0           ;increase..
  1288.         cmp.w   msng_songlen(a4),d0 ;highest section?
  1289.         blt.s   plr_nohisec
  1290.         moveq   #0,d0           ;yes.
  1291. plr_nohisec move.w  d0,mmd_psecnum(a2)  ;push back.
  1292.         add.w   d0,d0
  1293.         movea.l msng_sections(a4),a0    ;section table
  1294.         move.w  0(a0,d0.w),d0       ;new playseqlist number
  1295.         add.w   d0,d0
  1296.         add.w   d0,d0
  1297.         move.w  d0,mmd_pseq(a2)
  1298.         movea.l 0(a1,d0.w),a0       ;a0 = ptr to new PlaySeq
  1299.         moveq   #0,d0           ;playseq OFFSET = 0
  1300. ; -------- FETCH BLOCK NUMBER FROM SEQUENCE ------------------------------
  1301. plr_notagain    move.w  d0,mmd_pseqnum(a2)  ;remember new playseq pos
  1302.         add.w   d0,d0
  1303.         move.w  42(a0,d0.w),d0      ;get number of the block
  1304.         bpl.s   plr_changeblk   ;neg. values for future expansion
  1305.         bra.s   plr_skipseq ;(skip them)
  1306. ; ********* BELOW CODE FOR MMD0/MMD1 ONLY *******************************
  1307. plr_noMMD2_0    move.w  mmd_pseqnum(a2),d0  ;get play sequence number
  1308.         tst.b   (a3)
  1309.         bmi.s   plr_noadvseq_b      ;Bxx sets nextblock to -1
  1310.         addq.w  #1,d0           ;advance sequence number
  1311. plr_noadvseq_b  cmp.w   msng_songlen(a4),d0 ;is this the highest seq number??
  1312.         blt.s   plr_notagain_b      ;no.
  1313.         moveq   #0,d0           ;yes: restart song
  1314. plr_notagain_b  move.b  d0,mmd_pseqnum+1(a2)    ;remember new playseq-#
  1315.         lea msng_playseq(a4),a0 ;offset of sequence table
  1316.         move.b  0(a0,d0.w),d0       ;get number of the block
  1317. ; ********* BELOW CODE FOR BOTH FORMATS *********************************
  1318. plr_changeblk
  1319.     IFNE    CHECK
  1320.         cmp.w   msng_numblocks(a4),d0   ;beyond last block??
  1321.         blt.s   plr_nolstblk        ;no..
  1322.         moveq   #0,d0           ;play block 0
  1323.     ENDC
  1324. plr_nolstblk    move.w  d0,mmd_pblock(a2)   ;store block number
  1325. plr_nonewseq    clr.w   (a3)            ;clear this if F00 set it
  1326. plr_nochgblock  move.w  d1,mmd_pline(a2)    ;set new line number
  1327.  
  1328.     IFNE    HOLD
  1329.         lea trackdataptrs-DB(a6),a5
  1330.         movea.l mmd_blockarr(a2),a0
  1331.         move.w  mmd_pblock(a2),d0
  1332.         add.w   d0,d0
  1333.         add.w   d0,d0
  1334.         movea.l 0(a0,d0.w),a1   ;block...
  1335.         move.w  mmd_pline(a2),d0
  1336.         move.b  msng_tempo2(a4),d3  ;interrupts/note
  1337.     IFNE    PLAYMMD0
  1338.         cmp.b   #'1',3(a2)
  1339.         bge.s   plr_mmd1_2
  1340.         move.b  (a1),d7         ;# of tracks
  1341.         move.w  d0,d1
  1342.         add.w   d0,d0   ;d0 * 2
  1343.         add.w   d1,d0   ;+ d0 = d0 * 3
  1344.         mulu    d7,d0
  1345.         lea 2(a1,d0.w),a3
  1346.         subq.b  #1,d7
  1347. plr_chkholdb    movea.l (a5)+,a1        ;track data
  1348.         tst.b   trk_noteoffcnt(a1)  ;hold??
  1349.         bmi.s   plr_holdendb        ;no.
  1350.         move.b  (a3),d1         ;get the 1st byte..
  1351.         bne.s   plr_hold1b
  1352.         move.b  1(a3),d1
  1353.         and.b   #$f0,d1
  1354.         beq.s   plr_holdendb        ;don't hold
  1355.         bra.s   plr_hold2b
  1356. plr_hold1b  and.b   #$3f,d1         ;note??
  1357.         beq.s   plr_hold2b      ;no, cont hold..
  1358.         move.b  1(a3),d1
  1359.         and.b   #$0f,d1         ;get cmd
  1360.         subq.b  #3,d1           ;is there command 3 (slide)
  1361.         bne.s   plr_holdendb        ;no -> end holding
  1362. plr_hold2b  add.b   d3,trk_noteoffcnt(a1)   ;continue holding...
  1363. plr_holdendb    addq.l  #3,a3       ;next note
  1364.         dbf d7,plr_chkholdb
  1365.         bra.s   nonewnote
  1366. plr_mmd1_2
  1367.     ENDC
  1368.         move.w  (a1),d7     ;# of tracks
  1369.         add.w   d0,d0
  1370.         add.w   d0,d0   ;d0 = d0 * 4
  1371.         mulu    d7,d0
  1372.         lea 8(a1,d0.l),a3
  1373.         subq.b  #1,d7
  1374. plr_chkhold movea.l (a5)+,a1        ;track data
  1375.         tst.b   trk_noteoffcnt(a1)  ;hold??
  1376.         bmi.s   plr_holdend     ;no.
  1377.         move.b  (a3),d1         ;get the 1st byte..
  1378.         bne.s   plr_hold1
  1379.         move.b  1(a3),d0
  1380.         and.b   #$3F,d0
  1381.         beq.s   plr_holdend     ;don't hold
  1382.         bra.s   plr_hold2
  1383. plr_hold1   and.b   #$7f,d1         ;note??
  1384.         beq.s   plr_hold2       ;no, cont hold..
  1385.         move.b  2(a3),d1
  1386.         subq.b  #3,d1           ;is there command 3 (slide)
  1387.         bne.s   plr_holdend     ;no -> end holding
  1388. plr_hold2   add.b   d3,trk_noteoffcnt(a1)   ;continue holding...
  1389. plr_holdend addq.l  #4,a3       ;next note
  1390.         dbf d7,plr_chkhold
  1391.     ENDC    
  1392. nonewnote
  1393. ; SPECIAL... A GOOD PLACE FOR OWN HOOKS
  1394.         moveq   #0,d3
  1395.         move.b  mmd_counter(a2),d3
  1396. plr_fxtime  lea trackdataptrs-DB(a6),a3
  1397.         moveq   #0,d7   ;clear track count
  1398. plr_loop1   movea.l (a3)+,a5
  1399. ; SPECIAL...
  1400.         tst.w   d7
  1401.         bne.s   skipch0_1
  1402.         tst.w   _freech0
  1403.         bne.w   endl
  1404. skipch0_1
  1405. ; END OF SPECIAL
  1406.         moveq   #0,d4
  1407.         moveq   #0,d5
  1408.         moveq   #0,d6
  1409.         move.b  trk_cmd(a5),d6  ;get the fx number
  1410.         move.b  trk_cmdqual(a5),d4  ;and the last 2 #'s
  1411.     IFNE    MIDI
  1412.         tst.b   trk_prevmidin(a5)   ;is it MIDI??
  1413.         bne.w   midicmds
  1414.     ENDC
  1415.         cmp.w   #4,d7
  1416.     IFNE    MIDI
  1417.         bge.w   midicmds    ;no non-MIDI effects in tracks >= 4
  1418.     ENDC
  1419.     IFEQ    MIDI
  1420.         bge.w   endl
  1421.     ENDC
  1422.     IFNE    HOLD
  1423.         tst.b   trk_noteoffcnt(a5)
  1424.         bmi.s   plr_nowaitoff
  1425.         subq.b  #1,trk_noteoffcnt(a5)
  1426.         bpl.s   plr_nowaitoff
  1427.     IFNE    SYNTH
  1428.         tst.b   trk_synthtype(a5)       ;synth/hybrid??
  1429.         beq.s   plr_nosyndec
  1430.         move.b  trk_decay(a5),trk_volcmd+1(a5)  ;set volume command pointer
  1431.         clr.b   trk_volwait(a5)         ;abort WAI
  1432.         bra.s   plr_nowaitoff
  1433.     ENDC
  1434. plr_nosyndec:   move.b  trk_decay(a5),trk_fadespd(a5)   ;set fade...
  1435.         bne.s   plr_nowaitoff           ;if > 0, don't stop sound
  1436.         bset    d7,d5
  1437.         move.w  d5,$dff096          ;shut DMA...
  1438.         moveq   #0,d5
  1439.     ENDC
  1440. plr_nowaitoff:  
  1441.     IFNE    HOLD
  1442.         move.b  trk_fadespd(a5),d0  ;fade??
  1443.         beq.s   plr_nofade  ;no.
  1444.         sub.b   d0,trk_prevvol(a5)
  1445.         bpl.s   plr_nofade
  1446.         clr.b   trk_prevvol(a5)
  1447.         clr.b   trk_fadespd(a5)     ;fade no more
  1448.     ENDC
  1449. plr_nofade  add.b   d6,d6   ;* 2
  1450.         move.w  fx_table(pc,d6.w),d0
  1451.         jmp fxs(pc,d0.w)
  1452. fx_table    dc.w    fx_00-fxs,fx_01-fxs,fx_02-fxs,fx_03-fxs,fx_04-fxs
  1453.         dc.w    fx_05-fxs,fx_06-fxs,fx_07-fxs,fx_xx-fxs,fx_xx-fxs
  1454.         dc.w    fx_0a-fxs,fx_xx-fxs,fx_xx-fxs,fx_0d-fxs,fx_xx-fxs
  1455.         dc.w    fx_0f-fxs
  1456.         dc.w    fx_10-fxs,fx_11-fxs,fx_12-fxs,fx_13-fxs,fx_14-fxs
  1457.         dc.w    fx_xx-fxs,fx_xx-fxs,fx_xx-fxs,fx_18-fxs,fx_xx-fxs
  1458.         dc.w    fx_1a-fxs,fx_1b-fxs,fx_xx-fxs,fx_xx-fxs,fx_1e-fxs
  1459.         dc.w    fx_1f-fxs
  1460. fxs:
  1461. ;   **************************************** Effect 01 ******
  1462. fx_01:      tst.b   d3
  1463.         bne.s   fx_01nocnt0
  1464.         btst    #5,msng_flags(a4)   ;FLAG_STSLIDE??
  1465.         bne fx_xx
  1466. fx_01nocnt0 sub.w   d4,trk_prevper(a5)
  1467.         move.w  trk_prevper(a5),d5
  1468.         cmp.w   #113,d5
  1469.         bge plr_newper
  1470.         move.w  #113,d5
  1471.         move.w  d5,trk_prevper(a5)
  1472.         bra plr_newper
  1473. ;   **************************************** Effect 11 ******
  1474. fx_11       tst.b   d3
  1475.         bne fx_xx
  1476.         sub.w   d4,trk_prevper(a5)
  1477.         move.w  trk_prevper(a5),d5
  1478.         bra plr_newper
  1479. ;   **************************************** Effect 02 ******
  1480. fx_02:      tst.b   d3
  1481.         bne.s   fx_02nocnt0
  1482.         btst    #5,msng_flags(a4)
  1483.         bne fx_xx
  1484. fx_02nocnt0 add.w   d4,trk_prevper(a5)
  1485.         move.w  trk_prevper(a5),d5
  1486.         bra.w   plr_newper
  1487. ;   **************************************** Effect 12 ******
  1488. fx_12       tst.b   d3
  1489.         bne fx_xx
  1490.         add.w   d4,trk_prevper(a5)
  1491.         move.w  trk_prevper(a5),d5
  1492.         bra plr_newper
  1493. ;   **************************************** Effect 00 ******
  1494. fx_00:      tst.b   d4  ;both fxqualifiers are 0s: no arpeggio
  1495.         beq.w   fx_xx
  1496.         move.l  d3,d0
  1497.         divu    #3,d0
  1498.         swap    d0
  1499.         tst.w   d0
  1500.         bne.s   fx_arp12
  1501.         and.b   #$0f,d4
  1502.         add.b   (a5),d4
  1503.         bra.s   fx_doarp
  1504. fx_arp12:   subq.b  #1,d0
  1505.         bne.s   fx_arp2
  1506.         lsr.b   #4,d4
  1507.         add.b   (a5),d4
  1508.         bra.s   fx_doarp
  1509. fx_arp2:    move.b  (a5),d4
  1510. fx_doarp:   subq.b  #1,d4       ;-1 to make it 0 - 127
  1511.         add.b   msng_playtransp(a4),d4  ;add play transpose
  1512.         add.b   trk_stransp(a5),d4  ;add instrument transpose
  1513.         add.b   d4,d4
  1514.         movea.l trk_periodtbl(a5),a1
  1515.         move.w  0(a1,d4.w),d5
  1516.         bra.w   plr_newtmp
  1517. ;   **************************************** Effect 04 ******
  1518. fx_14       move.b  #6,trk_vibshift(a5)
  1519.         bra.s   vib_cont
  1520. fx_04       move.b  #5,trk_vibshift(a5)
  1521. vib_cont    tst.b   d3
  1522.         bne.s   nonvib
  1523.         move.b  d4,d1
  1524.         beq.s   nonvib
  1525.         and.w   #$0f,d1
  1526.         beq.s   plr_chgvibspd
  1527.         move.w  d1,trk_vibrsz(a5)
  1528. plr_chgvibspd:  and.b   #$f0,d4
  1529.         beq.s   nonvib
  1530.         lsr.b   #3,d4
  1531.         and.b   #$3e,d4
  1532.         move.b  d4,trk_vibrspd(a5)
  1533. nonvib:     move.b  trk_vibroffs(a5),d0
  1534.         lsr.b   #2,d0
  1535.         and.w   #$1f,d0
  1536.         moveq   #0,d1
  1537.         lea sinetable(pc),a0
  1538.         move.b  0(a0,d0.w),d5
  1539.         ext.w   d5
  1540.         muls    trk_vibrsz(a5),d5
  1541.         move.b  trk_vibshift(a5),d1
  1542.         asr.w   d1,d5
  1543.         add.w   trk_prevper(a5),d5
  1544.         move.b  trk_vibrspd(a5),d0
  1545.         add.b   d0,trk_vibroffs(a5)
  1546.         bra.w   plr_newtmp
  1547. ;   **************************************** Effect 06 ******
  1548. fx_06:      tst.b   d3
  1549.         bne.s   fx_06nocnt0
  1550.         btst    #5,msng_flags(a4)
  1551.         bne fx_xx
  1552. fx_06nocnt0 bsr.s   plr_volslide        ;Volume slide
  1553.         bra.s   nonvib          ;+ Vibrato
  1554. ;   **************************************** Effect 07 ******
  1555. fx_07       tst.b   d3
  1556.         bne.s   nontre
  1557.         move.b  d4,d1
  1558.         beq.s   nontre
  1559.         and.w   #$0f,d1
  1560.         beq.s   plr_chgtrespd
  1561.         move.w  d1,trk_tremsz(a5)
  1562. plr_chgtrespd   and.b   #$f0,d4
  1563.         beq.s   nonvib
  1564.         lsr.b   #2,d4
  1565.         and.b   #$3e,d4
  1566.         move.b  d4,trk_tremspd(a5)
  1567. nontre      move.b  trk_tremoffs(a5),d0
  1568.         lsr.b   #3,d0
  1569.         and.w   #$1f,d0
  1570.         moveq   #0,d1
  1571.         lea sinetable(pc),a0
  1572.         move.b  0(a0,d0.w),d5
  1573.         ext.w   d5
  1574.         muls    trk_tremsz(a5),d5
  1575.         asr.w   #7,d5
  1576.         move.b  trk_tremspd(a5),d0
  1577.         add.b   d0,trk_tremoffs(a5)
  1578.         move.b  trk_prevvol(a5),d1
  1579.         add.b   d5,d1
  1580.         bpl.s   tre_pos
  1581.         moveq   #0,d1
  1582. tre_pos     cmp.b   #64,d1
  1583.         ble.s   tre_no2hi
  1584.         moveq   #64,d1
  1585. tre_no2hi   move.b  d1,trk_tempvol(a5)
  1586.         bra.w   fx_xx
  1587. ;   **************************************** Effect 0D/0A ***
  1588. fx_0a:
  1589. fx_0d:      tst.b   d3
  1590.         bne.s   fx_0dnocnt0
  1591.         btst    #5,msng_flags(a4)
  1592.         bne fx_xx
  1593. fx_0dnocnt0 bsr.s   plr_volslide
  1594.         bra fx_xx
  1595. ;   ********* VOLUME SLIDE FUNCTION *************************
  1596. plr_volslide    move.b  d4,d0
  1597.         moveq   #0,d1
  1598.         move.b  trk_prevvol(a5),d1 ;move previous vol to d1
  1599.         and.b   #$f0,d0
  1600.         bne.s   crescendo
  1601.         sub.b   d4,d1   ;sub from prev. vol
  1602. voltest0    bpl.s   novolover64
  1603.         moveq   #0,d1   ;volumes under zero not accepted!!!
  1604.         bra.s   novolover64
  1605. crescendo:  lsr.b   #4,d0
  1606.         add.b   d0,d1
  1607. voltest     cmp.b   #64,d1
  1608.         ble.s   novolover64
  1609.         moveq   #64,d1
  1610. novolover64 move.b  d1,trk_prevvol(a5)
  1611.         rts
  1612. ;   **************************************** Effect 1A ******
  1613. fx_1a       tst.b   d3
  1614.         bne fx_xx
  1615.         move.b  trk_prevvol(a5),d1
  1616.         add.b   d4,d1
  1617.         bsr.s   voltest
  1618.         bra fx_xx
  1619. ;   **************************************** Effect 1B ******
  1620. fx_1b       tst.b   d3
  1621.         bne fx_xx
  1622.         move.b  trk_prevvol(a5),d1
  1623.         sub.b   d4,d1
  1624.         bsr.s   voltest0
  1625.         bra fx_xx
  1626. ;   **************************************** Effect 05 ******
  1627. fx_05:      tst.b   d3
  1628.         bne.s   fx_05nocnt0
  1629.         btst    #5,msng_flags(a4)
  1630.         bne fx_xx
  1631. fx_05nocnt0 bsr.s   plr_volslide        ;Volume slide
  1632.         bra.s   fx_03nocnt0
  1633. ;   **************************************** Effect 03 ******
  1634. fx_03:      tst.b   d3
  1635.         bne.s   fx_03nocnt0
  1636.         btst    #5,msng_flags(a4)
  1637.         bne fx_xx
  1638. fx_03nocnt0 move.w  trk_porttrgper(a5),d0   ;d0 = target period
  1639.         beq.w   fx_xx   ;no target period specified
  1640.         move.w  trk_prevper(a5),d1  ;d1 = curr. period
  1641.         move.b  trk_prevportspd(a5),d4  ;get prev. speed
  1642.         cmp.w   d0,d1
  1643.         bhi.s   subper  ;curr. period > target period
  1644.         add.w   d4,d1   ;add the period
  1645.         cmp.w   d0,d1
  1646.         bge.s   targreached
  1647.         bra.s   targnreach
  1648. subper:     sub.w   d4,d1   ;subtract
  1649.         cmp.w   d0,d1   ;compare current period to target period
  1650.         bgt.s   targnreach
  1651. targreached:    move.w  trk_porttrgper(a5),d1 ;eventually push target period
  1652.         clr.w   trk_porttrgper(a5) ;now we can forget everything
  1653. targnreach: move.w  d1,trk_prevper(a5)
  1654.         move.w  d1,d5
  1655.         bra.s   plr_newper
  1656. ;   **************************************** Effect 13 ******
  1657. fx_13:      move.w  trk_prevper(a5),d5 ;this is very simple: get the old period
  1658.         cmp.b   #3,d3       ;and..
  1659.         bge.s   plr_newper  ;if counter < 3
  1660.         sub.w   d4,d5   ;subtract effect qualifier
  1661.         bra.s   plr_newper
  1662. ;   **************************************** Effect 10 ******
  1663. fx_10:
  1664.     IFNE    MIDI
  1665.         tst.b   d3
  1666.         bne.s   fx_xx
  1667.         move.w  d4,d0
  1668.         bsr.w   _InitMIDIDump
  1669.     ENDC
  1670.         bra.s   fx_xx
  1671. ;   **************************************** Effect 1E ******
  1672. fx_1e       tst.w   blkdelay-DB(a6)
  1673.         bne.s   fx_xx
  1674.         addq.w  #1,d4
  1675.         move.w  d4,blkdelay-DB(a6)
  1676.         bra.s   fx_xx
  1677. ;   **************************************** Effect 18 ******
  1678. fx_18       cmp.b   d4,d3
  1679.         bne.s   fx_xx
  1680.         clr.b   trk_prevvol(a5)
  1681.         bra.s   fx_xx
  1682. ;   **************************************** Effect 1F ******
  1683. fx_1f       move.b  d4,d1
  1684.         lsr.b   #4,d4       ;note delay
  1685.         beq.s   nonotedelay
  1686.         cmp.b   d4,d3       ;compare to counter
  1687.         blt.s   fx_xx       ;tick not reached
  1688.         bne.s   nonotedelay
  1689.         bsr playfxnote  ;trigger note
  1690. nonotedelay and.w   #$0f,d1     ;retrig?
  1691.         beq.s   fx_xx
  1692.         moveq   #0,d0
  1693.         move.b  d3,d0
  1694.         divu    d1,d0
  1695.         swap    d0      ;get modulo of counter/tick
  1696.         tst.w   d0
  1697.         bne.s   fx_xx
  1698.         bsr playfxnote  ;retrigger
  1699.         bra.s   fx_xx
  1700. ;   **************************************** Effect 0F ******
  1701. fx_0f       bsr cmd_F
  1702. ;   *********************************************************
  1703. plr_newper
  1704. fx_xx
  1705.     IFNE    SYNTH
  1706.         move.l  trk_synthptr(a5),d0
  1707.         beq.s   plr_nosynth
  1708.         bsr.w   synth_start
  1709.         bra.s   plr_tmpper
  1710. plr_newtmp  move.l  trk_synthptr(a5),d0
  1711.         beq.s   plr_tmpper
  1712.         bsr.w   synth_start2
  1713.         bra.s   plr_tmpper
  1714.     ENDC
  1715. plr_nosynth move.w  trk_prevper(a5),d5
  1716.     IFEQ    SYNTH
  1717. plr_newtmp
  1718.     ENDC
  1719. plr_tmpper  movea.l trk_audioaddr(a5),a1    ;get channel address
  1720.         move.w  d5,ac_per(a1)       ;push period
  1721.         beq.s   endl
  1722.         move.b  trk_tempvol(a5),d0
  1723.         bmi.s   plr_notmpvol
  1724.         move.b  d0,ac_vol+1(a1)
  1725.         st  trk_tempvol(a5)
  1726.         bra.s   endl
  1727. plr_notmpvol    move.b  trk_prevvol(a5),ac_vol+1(a1)    ;get volume & push it
  1728. endl:       addq.b  #1,d7           ;increment channel number
  1729.         cmp.w   numtracks-DB(a6),d7 ;all channels done???
  1730.         blt.w   plr_loop1       ;not yet!!!
  1731. plr_endfx:  ;turn on DMA
  1732.         move.w  dmaonmsk-DB(a6),d0  ;dmaonmsk contains the mask of
  1733.     IFNE    MIDI
  1734.         beq.s   sdma_nodmaon    ;the channels that must be turned on
  1735.     ENDC
  1736.     IFEQ    MIDI
  1737.         beq.s   plr_exit
  1738.     ENDC    
  1739.         bset    #15,d0  ;DMAF_SETCLR: set these bits in dmacon
  1740.         moveq   #80,d1
  1741. ; The following line makes the playroutine one scanline slower. If your
  1742. ; song works well without the following instruction, you can leave it out.
  1743.     IFNE    SYNTH
  1744.         add.w   d1,d1   ;sometimes double wait time is required
  1745.     ENDC
  1746.         bsr.s   _Wait1line
  1747.         move.w  d0,$dff096  ;do that!!!
  1748.         moveq   #80,d1
  1749.         bsr.s   _Wait1line
  1750.         lea trackdataptrs-DB(a6),a1
  1751.         bsr.s   pushnewvals
  1752.         bsr.s   pushnewvals
  1753.         bsr.s   pushnewvals
  1754.         bsr.s   pushnewvals
  1755.     IFNE    MIDI
  1756. sdma_nodmaon    lea bytesinnotebuff-DB(a6),a0
  1757.         move.w  (a0)+,d0
  1758.         beq.s   plr_exit
  1759.         bsr.w   _AddMIDId
  1760.     ENDC
  1761. plr_exit:   movem.l (sp)+,d2-d7/a2-a6
  1762.         moveq   #1,d0
  1763.         rts
  1764.  
  1765. _Wait1line: move.w  d0,-(sp)    ;d1 = vsync counters to wait - 1
  1766. wl0:        move.b  $dff007,d0
  1767. wl1:        cmp.b   $dff007,d0
  1768.         beq.s   wl1
  1769.         dbf d1,wl0
  1770.         move.w  (sp)+,d0
  1771.         rts
  1772. pushnewvals:    movea.l (a1)+,a5
  1773.         lsr.b   #1,d0
  1774.         bcc.s   rpnewv
  1775.         move.l  trk_sampleptr(a5),d1
  1776.         beq.s   rpnewv
  1777.         movea.l trk_audioaddr(a5),a0
  1778.         move.l  d1,ac_ptr(a0)
  1779.         move.w  trk_samplelen(a5),ac_len(a0)
  1780. rpnewv:     rts
  1781.  
  1782. cmd_F       cmp.b   #$f1,d4
  1783.         bne.s   no0ff1
  1784.         cmp.b   #3,d3
  1785.         beq.s   playfxnote
  1786.         rts
  1787. no0ff1:     cmp.b   #$f2,d4
  1788.         bne.s   no0ff2
  1789.         cmp.b   #3,d3
  1790.         beq.s   playfxnote
  1791.         rts
  1792. no0ff2:     cmp.b   #$f3,d4
  1793.         bne.s   no0ff3
  1794.         move.b  d3,d0
  1795.         beq.s   cF_rts
  1796.         and.b   #1,d0       ;is 2 or 4
  1797.         bne.s   cF_rts
  1798. playfxnote: moveq   #0,d1
  1799.         move.b  (a5),d1     ;get note # of previous note
  1800.         beq.s   cF_rts
  1801.         move.b  trk_noteoffcnt(a5),d0   ;get hold counter
  1802.         bmi.s   pfxn_nohold     ;no hold, or hold over
  1803.         add.b   d3,d0           ;increase by counter val
  1804.         bra.s   pfxn_hold
  1805. pfxn_nohold move.b  trk_inithold(a5),d0 ;get initial hold
  1806.         bne.s   pfxn_hold
  1807.         st  d0
  1808. pfxn_hold   move.b  d0,trk_noteoffcnt(a5)
  1809.         movem.l d3/a3,-(sp)
  1810.         moveq   #0,d3
  1811.         move.b  trk_previnstr(a5),d3    ;and prev. sample #
  1812.         movea.l trk_previnstra(a5),a3
  1813.         bsr _PlayNote
  1814.         movem.l (sp)+,d3/a3
  1815. cF_rts      rts
  1816. no0ff3:     cmp.b   #$f4,d4     ;triplet cmd 1
  1817.         bne.s   no0ff4
  1818.         moveq   #0,d0
  1819.         move.b  msng_tempo2(a4),d0
  1820.         divu    #3,d0
  1821.         cmp.b   d0,d3
  1822.         beq.s   playfxnote
  1823.         rts
  1824. no0ff4      cmp.b   #$f5,d4     ;triplet cmd 2
  1825.         bne.s   no0ff5
  1826.         moveq   #0,d0
  1827.         move.b  msng_tempo2(a4),d0
  1828.         divu    #3,d0
  1829.         add.w   d0,d0
  1830.         cmp.b   d0,d3
  1831.         beq.s   playfxnote
  1832.         rts
  1833. no0ff5      cmp.b   #$f8,d4     ;f8 = filter off
  1834.         beq.s   plr_filteroff
  1835.         cmp.b   #$f9,d4     ;f9 = filter on
  1836.         bne.s   cF_rts
  1837.         bclr    #1,$bfe001
  1838.         rts
  1839. plr_filteroff:  bset    #1,$bfe001
  1840.         rts
  1841.  
  1842. _SetTempo:
  1843.     IFNE    CIAB
  1844.         move.l  _module-DB(a6),d1
  1845.         beq.s   ST_x
  1846.         move.l  d1,a0
  1847.         movea.l mmd_songinfo(a0),a0
  1848.         btst    #5,msng_flags2(a0)
  1849.         bne.s   ST_bpm
  1850.         cmp.w   #10,d0  ;If tempo <= 10, use SoundTracker tempo
  1851.         bhi.s   calctempo
  1852.         subq.b  #1,d0
  1853.         add.w   d0,d0
  1854.         move.w  sttempo+2(pc,d0.w),d1
  1855.         bra.s   pushtempo
  1856. calctempo:  move.l  timerdiv-DB(a6),d1
  1857.         divu    d0,d1
  1858. pushtempo:  movea.l craddr+4-DB(a6),a0
  1859.         move.b  d1,(a0)     ;and set the CIA timer
  1860.         lsr.w   #8,d1
  1861.         movea.l craddr+8-DB(a6),a0
  1862.         move.b  d1,(a0)
  1863.     ENDC
  1864. ST_x        rts ;   vv-- These values are the SoundTracker tempos (approx.)
  1865. sttempo:    dc.w    $0f00
  1866.     IFNE    CIAB
  1867.         dc.w    2417,4833,7250,9666,12083,14500,16916,19332,21436,24163
  1868. ST_bpm      move.b  msng_flags2(a0),d1
  1869.         and.w   #$1F,d1
  1870.         addq.b  #1,d1
  1871.         mulu    d1,d0
  1872.         move.l  bpmdiv-DB(a6),d1
  1873.         divu    d0,d1
  1874.         bra.s   pushtempo
  1875.     ENDC
  1876.  
  1877.     IFNE    MIDI
  1878. midicmds
  1879.     IFNE    HOLD
  1880.         tst.b   trk_noteoffcnt(a5)
  1881.         bmi.s   midi_nowaitoff
  1882.         subq.b  #1,trk_noteoffcnt(a5)
  1883.         bpl.s   midi_nowaitoff
  1884.         move.l  a5,a1
  1885.         move.b  trk_prevmidin(a5),d1
  1886.         beq.s   midi_nowaitoff  ;no note
  1887.         lea noteondata-DB(a6),a0
  1888.         bsr.w   choff_midi
  1889. midi_nowaitoff:
  1890.     ENDC
  1891.         add.b   d6,d6   ;* 2
  1892.         move.w  midicmd_table(pc,d6.w),d0
  1893.         jmp midifx(pc,d0.w)
  1894. midicmd_table:  dc.w    mfx_00-midifx,mfx_01-midifx,mfx_02-midifx,mfx_03-midifx,mfx_04-midifx
  1895.         dc.w    mfx_05-midifx,endl-midifx,endl-midifx,endl-midifx,endl-midifx
  1896.         dc.w    mfx_0a-midifx,endl-midifx,endl-midifx,mfx_0d-midifx,mfx_0e-midifx
  1897.         dc.w    mfx_0f-midifx
  1898.         dc.w    mfx_10-midifx,endl-midifx,endl-midifx,mfx_13-midifx
  1899.         dc.w    endl-midifx,endl-midifx,endl-midifx,mfx_17-midifx
  1900.         dc.w    endl-midifx,endl-midifx,endl-midifx,endl-midifx
  1901.         dc.w    endl-midifx,endl-midifx,endl-midifx,mfx_1f-midifx
  1902. midifx      
  1903. mfx_01      lea prevmidipbend-DB(a6),a0
  1904.         moveq   #0,d1
  1905.         move.b  trk_prevmidich(a5),d1   ;get previous midi channel
  1906.         add.b   d1,d1       ;UWORD index
  1907.         tst.b   d4      ;x100??
  1908.         beq.s   resetpbend
  1909.         move.w  0(a0,d1.w),d0   ;get previous pitch bend
  1910.         lsl.w   #3,d4       ;multiply bend value by 8
  1911.         add.w   d4,d0
  1912.         cmp.w   #$3fff,d0
  1913.         bls.s   bendpitch
  1914.         move.w  #$3fff,d0
  1915. bendpitch:  move.w  d0,0(a0,d1.w)   ;save current pitch bend
  1916.         lsr.b   #1,d1       ;back to UBYTE
  1917.         or.b    #$e0,d1
  1918.         lea noteondata-DB(a6),a0
  1919.         move.b  d1,(a0)     ;midi command & channel
  1920.         move.b  d0,1(a0)    ;lower value
  1921.         and.b   #$7f,1(a0)  ;clear bit 7
  1922.         lsr.w   #7,d0
  1923.         and.b   #$7f,d0     ;clr bit 7
  1924.         move.b  d0,2(a0)    ;higher 7 bits
  1925.         moveq   #3,d0
  1926.         bsr.w   _AddMIDId
  1927.         bra.w   endl
  1928.  
  1929. mfx_02      lea prevmidipbend-DB(a6),a0
  1930.         moveq   #0,d1
  1931.         move.b  trk_prevmidich(a5),d1
  1932.         add.b   d1,d1
  1933.         tst.b   d4
  1934.         beq.s   resetpbend  ;x200??
  1935.         move.w  0(a0,d1.w),d0
  1936.         lsl.w   #3,d4
  1937.         sub.w   d4,d0
  1938.         bpl.s   bendpitch   ;not under 0
  1939.         moveq   #0,d0
  1940.         bra.s   bendpitch
  1941. resetpbend: tst.b   d3      ;d3 = counter (remember??)
  1942.         bne.w   endl
  1943.         move.w  #$2000,d0
  1944.         bra.s   bendpitch
  1945. mfx_13
  1946. mfx_03      tst.b   d3
  1947.         bne.w   endl
  1948.         lea prevmidipbend-DB(a6),a0
  1949.         moveq   #0,d1
  1950.         move.b  trk_prevmidich(a5),d1
  1951.         add.b   d1,d1
  1952.         move.b  d4,d0
  1953.         add.b   #128,d0
  1954.         lsl.w   #6,d0
  1955.         bra.s   bendpitch
  1956.  
  1957. mfx_0d      tst.b   d3
  1958.         bne.w   endl
  1959.         lea noteondata+1-DB(a6),a0  ;CHANNEL AFTERTOUCH
  1960.         move.b  d4,(a0) ;value
  1961.         bmi.w   endl
  1962.         move.b  trk_prevmidich(a5),-(a0)
  1963.         or.b    #$d0,(a0)
  1964.         moveq   #2,d0
  1965.         bsr.w   _AddMIDId
  1966.         bra.w   endl
  1967.  
  1968. mfx_0a      tst.b   d3
  1969.         bne.w   endl
  1970.         lea noteondata+2-DB(a6),a0  ;POLYPHONIC AFTERTOUCH
  1971.         and.b   #$7f,d4
  1972.         move.b  d4,(a0)
  1973.         move.b  trk_prevmidin(a5),-(a0)
  1974.         ble.w   endl
  1975.         move.b  trk_prevmidich(a5),-(a0)
  1976.         or.b    #$A0,(a0)
  1977.         moveq   #3,d0
  1978.         bsr.w   _AddMIDId
  1979.         bra.w   endl
  1980.  
  1981. mfx_17      moveq   #$07,d0     ;07 = VOLUME
  1982.         bra.s   pushctrldata
  1983.  
  1984. mfx_04      moveq   #$01,d0     ;01 = MODULATION WHEEL
  1985.         bra.s   pushctrldata
  1986.  
  1987. mfx_0e      moveq   #$0a,d0
  1988. pushctrldata    tst.b   d3      ;do it only once in a note
  1989.         bne.w   endl        ;(when counter = 0)
  1990.         lea noteondata+2-DB(a6),a0 ;push "control change" data,
  1991.         move.b  d4,(a0)     ;second databyte
  1992.         bmi.w   endl        ;$0 - $7F only
  1993.         move.b  d0,-(a0)    ;1st databyte
  1994.         move.b  trk_prevmidich(a5),-(a0)    ;MIDI channel
  1995.         or.b    #$b0,(a0)   ;command (B)
  1996.         moveq   #3,d0
  1997.         bsr.w   _AddMIDId
  1998.         bra.w   endl
  1999.  
  2000. mfx_05      and.b   #$7f,d4     ;set contr. value of curr. MIDI ch.
  2001.         move.b  trk_prevmidich(a5),d6
  2002.         lea midicontrnum-DB(a6),a0
  2003.         adda.w  d6,a0
  2004.         move.b  d4,(a0)
  2005.         bra.w   endl
  2006.  
  2007. mfx_0f      cmp.b   #$fa,d4     ;hold pedal ON
  2008.         bne.s   nomffa
  2009.         moveq   #$40,d0
  2010.         moveq   #$7f,d4
  2011.         bra.s   pushctrldata
  2012. nomffa      cmp.b   #$fb,d4     ;hold pedal OFF
  2013.         bne.s   mfx_0f_2
  2014.         moveq   #$40,d0
  2015.         moveq   #$00,d4
  2016.         bra.s   pushctrldata
  2017. mfx_0f_2    bsr.w   cmd_F
  2018.         bra.w   endl
  2019.  
  2020. mfx_00      tst.b   d4
  2021.         beq.w   endl
  2022.         and.b   #$7f,d4
  2023.         move.b  trk_prevmidich(a5),d6
  2024.         lea midicontrnum-DB(a6),a0
  2025.         move.b  0(a0,d6.w),d0
  2026.         bra.s   pushctrldata
  2027.  
  2028. mfx_10      tst.b   d3
  2029.         bne.w   endl
  2030.         move.w  d4,d0
  2031.         bsr.w   _InitMIDIDump
  2032.         bra.w   endl
  2033.  
  2034. mfx_1f      move.b  d4,d1
  2035.         lsr.b   #4,d4       ;note delay
  2036.         beq.s   nonotedelay_m
  2037.         cmp.b   d4,d3       ;compare to counter
  2038.         blt endl        ;tick not reached
  2039.         bne.s   nonotedelay_m
  2040.         bsr playfxnote  ;trigger note
  2041. nonotedelay_m   and.w   #$0f,d1     ;retrig?
  2042.         beq endl
  2043.         moveq   #0,d0
  2044.         move.b  d3,d0
  2045.         divu    d1,d0
  2046.         swap    d0      ;get modulo of counter/tick
  2047.         tst.w   d0
  2048.         bne endl
  2049.         bsr playfxnote  ;retrigger
  2050.         bra endl
  2051.  
  2052. _ResetMIDI: movem.l d2/a2/a6,-(sp)
  2053.         movea.l 4.w,a6      ;ExecBase
  2054.         jsr -$78(a6)    ;Disable()
  2055.         lea DB,a6
  2056. ; Clear preset memory
  2057.         lea prevmidicpres-DB(a6),a0
  2058.         moveq   #7,d2
  2059. RM_loop0    clr.l   (a0)+   ;force presets to be set again
  2060.         dbf d2,RM_loop0
  2061.         clr.b   lastcmdbyte
  2062. ; Reset pitchbenders & modulation wheels
  2063.         lea midiresd-DB(a6),a2
  2064.         move.b  #$e0,(a2)
  2065.         move.b  #$b0,3(a2)
  2066.         moveq   #15,d2
  2067. respbendl:  movea.l a2,a0
  2068.         moveq   #6,d0
  2069.         bsr.w   _AddMIDId
  2070.         addq.b  #1,(a2)
  2071.         addq.b  #1,3(a2)
  2072.         dbf d2,respbendl
  2073.         lea prevmidipbend-DB(a6),a2
  2074.         moveq   #15,d2
  2075. resprevpbends:  move.w  #$2000,(a2)+
  2076.         dbf d2,resprevpbends
  2077. ; Clear dump variables
  2078.         clr.b   sysx-DB(a6)
  2079.         lea dumpqueue-DB(a6),a0
  2080.         move.l  a0,dqreadptr-DB(a6)
  2081.         move.l  a0,dqwriteptr-DB(a6)
  2082.         clr.w   dqentries-DB(a6)
  2083. ; Enable & exit
  2084.         movea.l 4.w,a6
  2085.         jsr -$7e(a6)    ;Enable()
  2086.         movem.l (sp)+,d2/a2/a6
  2087.         rts
  2088.     ENDC
  2089.  
  2090. ; *************************************************************************
  2091. ; *************************************************************************
  2092. ; ***********          P U B L I C   F U N C T I O N S          ***********
  2093. ; *************************************************************************
  2094. ; *************************************************************************
  2095.  
  2096.     IFEQ    EASY
  2097.         XDEF    _InitModule,_PlayModule
  2098.         XDEF    _InitPlayer,_RemPlayer,_StopPlayer
  2099.         XDEF    _ContModule
  2100.     ENDC
  2101.  
  2102. ; *************************************************************************
  2103. ; InitModule(a0 = module) -- extract expansion data etc.. from V3.xx module
  2104. ; *************************************************************************
  2105.  
  2106. _InitModule:    movem.l a2-a3/d2,-(sp)
  2107.         move.l  a0,-(sp)
  2108.         beq IM_exit         ;0 => xit
  2109.     IFNE    RELVOL
  2110.         movea.l mmd_songinfo(a0),a1 ;MMD0song
  2111.         move.b  msng_mastervol(a1),d0   ;d0 = mastervol
  2112.         ext.w   d0
  2113.         lea trackdataptrs,a2
  2114.         cmp.b   #'2',3(a0)      ;MMD2?
  2115.         bne.s   IM_mmd01
  2116.         move.w  msng_numtracks(a1),d1
  2117.         subq.w  #1,d1
  2118.         movea.l msng_trkvoltbl(a1),a1
  2119.         bra.s   IM_loop0
  2120. IM_mmd01    lea msng_trkvol(a1),a1  ;a1 = trkvol
  2121.         moveq   #MAX_MMD1_TRACKS-1,d1
  2122. IM_loop0    move.b  (a1)+,d2    ;get vol...
  2123.         ext.w   d2
  2124.         move.l  (a2)+,a3    ;pointer to track data
  2125.         mulu    d0,d2       ;mastervol * trackvol
  2126.         lsr.w   #4,d2
  2127.         move.w  d2,trk_trackvol(a3)
  2128.         dbf d1,IM_loop0
  2129.     ENDC
  2130.     IFNE    SYNTH
  2131.         lea trackdataptrs,a2
  2132.         moveq   #3,d1
  2133. IM_loop1    move.l  (a2)+,a3
  2134.         clr.l   trk_synthptr(a3)
  2135.         clr.b   trk_synthtype(a3)
  2136.         dbf d1,IM_loop1
  2137.     ENDC
  2138.         lea holdvals,a2
  2139.         movea.l a0,a3
  2140.         move.l  mmd_expdata(a0),d0  ;expdata...
  2141.     IFEQ    MIDI
  2142.         beq.s   IM_clrhlddec        ;none here
  2143.     ENDC
  2144.     IFNE    MIDI
  2145.         beq.w   IM_clrhlddec
  2146.     ENDC
  2147.         move.l  d0,a1
  2148.         move.l  4(a1),d0        ;exp_smp
  2149.     IFEQ    MIDI
  2150.         beq.s   IM_clrhlddec    ;again.. nothing
  2151.     ENDC
  2152.     IFNE    MIDI
  2153.         beq.w   IM_clrhlddec
  2154.     ENDC
  2155.         move.l  d0,a0       ;InstrExt...
  2156.         move.w  8(a1),d2    ;# of entries
  2157.     IFEQ    MIDI
  2158.         beq.s   IM_clrhlddec
  2159.     ENDC
  2160.     IFNE    MIDI
  2161.         beq.w   IM_clrhlddec
  2162.     ENDC
  2163.         subq.w  #1,d2       ;-1 (for dbf)
  2164.         move.w  10(a1),d0   ;entry size
  2165.         movea.l mmd_songinfo(a3),a3 ;MMD0song
  2166.     IFNE    MIDI
  2167.         lea 4*63(a2),a1 ;pointer to ext_midipsets...
  2168.     ENDC
  2169. IM_loop2    clr.b   126(a2)     ;clear finetune
  2170.         cmp.w   #3,d0
  2171.         ble.s   IM_noftune
  2172.         move.b  3(a0),126(a2)   ;InstrExt.finetune -> finetune
  2173. IM_noftune  clr.b   189(a2)     ;clear flags
  2174.         cmp.w   #6,d0
  2175.         blt.s   IM_noflags
  2176.         move.b  5(a0),189(a2)   ;InstrExt.flags -> flags
  2177.         bra.s   IM_gotflags
  2178. IM_noflags  cmp.w   #1,inst_replen(a3)
  2179.         bls.s   IM_gotflags
  2180.         bset    #0,189(a2)
  2181. IM_gotflags
  2182.     IFNE    MIDI
  2183.         cmp.w   #2,d0
  2184.         ble.s   IM_nsmnoff
  2185.         tst.b   2(a0)       ;suppress MIDI note off?
  2186.         beq.s   IM_nsmnoff
  2187.         bset    #7,inst_midich(a3)
  2188. IM_nsmnoff  move.b  inst_midipreset(a3),d1
  2189.         ext.w   d1
  2190.         move.w  d1,(a1)
  2191.         cmp.w   #8,d0
  2192.         ble.s   IM_nolongpset
  2193.         move.w  6(a0),(a1)  ;-> ext_midipsets
  2194.         btst    #1,5(a0)
  2195.         beq.s   IM_nolongpset
  2196.         bset    #6,inst_midich(a3)
  2197. IM_nolongpset   addq.l  #2,a1
  2198.     ENDC
  2199.         move.b  1(a0),63(a2)    ;InstrExt.decay -> decay
  2200.         move.b  (a0),(a2)+  ;InstrExt.hold -> holdvals
  2201.         adda.w  d0,a0       ;ptr to next InstrExt
  2202.         addq.l  #8,a3       ;next instrument...
  2203.         dbf d2,IM_loop2
  2204.         bra.s   IM_exit
  2205. IM_clrhlddec    move.w  #3*63-1,d0  ;no InstrExt => clear holdvals/decays
  2206. IM_loop3    clr.w   (a2)+       ;..and finetunes/flags/ext_psets
  2207.         dbf d0,IM_loop3
  2208.         movea.l (sp),a0
  2209. ; -------- For (very old) MMDs, with no InstrExt, set flags/SSFLG_LOOP,
  2210. ; -------- also copy inst_midipreset to ext_midipsets.
  2211.         movea.l mmd_songinfo(a0),a3
  2212.         lea flags,a2
  2213.     IFNE    MIDI
  2214.         lea ext_midipsets,a1
  2215.     ENDC
  2216.         moveq   #62,d0
  2217. IM_loop4    cmp.w   #1,inst_replen(a3)
  2218.         bls.s   IM_noreptflg
  2219.         bset    #0,(a2)
  2220. IM_noreptflg    addq.l  #1,a2
  2221.     IFNE    MIDI
  2222.         move.b  inst_midipreset(a3),d1
  2223.         ext.w   d1
  2224.         move.w  d1,(a1)+
  2225.     ENDC
  2226.         addq.l  #8,a3       ;next inst
  2227.         dbf d0,IM_loop4
  2228. IM_exit     addq.l  #4,sp
  2229.         movem.l (sp)+,a2-a3/d2
  2230.         rts
  2231. ; *************************************************************************
  2232. ; InitPlayer() -- allocate interrupt, audio, serial port etc...
  2233. ; *************************************************************************
  2234. _InitPlayer:
  2235.     IFNE    MIDI
  2236.         bsr.w   _GetSerial
  2237.         tst.l   d0
  2238.         bne.s   IP_error
  2239.     ENDC
  2240.         bsr.w   _AudioInit
  2241.         tst.l   d0
  2242.         bne.s   IP_error
  2243.         rts
  2244. IP_error    bsr.s   _RemPlayer
  2245.         moveq   #-1,d0
  2246.         rts
  2247. ; *************************************************************************
  2248. ; RemPlayer() -- free interrupt, audio, serial port etc..
  2249. ; *************************************************************************
  2250. _RemPlayer: move.b  _timeropen,d0
  2251.         beq.s   RP_notimer  ;timer is not ours
  2252.         bsr.s   _StopPlayer
  2253. RP_notimer: bsr.w   _AudioRem
  2254.     IFNE    MIDI
  2255.         bra.w   _FreeSerial
  2256.     ELSEIF
  2257.         rts
  2258.     ENDC
  2259. ; *************************************************************************
  2260. ; StopPlayer() -- stop the music
  2261. ; *************************************************************************
  2262. _StopPlayer:    lea DB,a1
  2263.         move.b  _timeropen-DB(a1),d0
  2264.         beq.s   SP_end      ;res. alloc fail.
  2265.     IFNE    CIAB
  2266.         movea.l craddr-DB(a1),a0
  2267.         bclr    #0,(a0)     ;stop timer
  2268.     ENDC
  2269.         move.l  _module-DB(a1),d0
  2270.         beq.s   SP_nomod
  2271.         move.l  d0,a0
  2272.         clr.w   mmd_pstate(a0)
  2273.         clr.l   _module-DB(a1)
  2274. SP_nomod
  2275.     IFNE    MIDI
  2276.         clr.b   lastcmdbyte-DB(a1)
  2277.     ENDC
  2278.         bra.w   SoundOff
  2279. SP_end      rts
  2280.  
  2281.  
  2282. _ContModule tst.b   _timeropen
  2283.         beq.s   SP_end
  2284.         movea.l craddr,a1
  2285.         bclr    #0,(a1)
  2286.         move.l  a0,-(sp)
  2287.         bsr.w   SoundOff
  2288.         move.l  (sp)+,a0
  2289.         moveq   #0,d0
  2290.         bra.s   contpoint
  2291. ; *************************************************************************
  2292. ; PlayModule(a0 = module)  -- initialize & play it!
  2293. ; *************************************************************************
  2294. _PlayModule:    st  d0
  2295. contpoint   movem.l a0/d0,-(sp)
  2296.         bsr _InitModule
  2297.         movem.l (sp)+,a0/d0
  2298.         move.l  a6,-(sp)
  2299.         lea DB,a6
  2300.         tst.b   _timeropen-DB(a6)
  2301.         beq PM_end      ;resource allocation failure
  2302.         move.l  a0,d1
  2303.         beq PM_end      ;module failure
  2304.     IFNE    CIAB
  2305.         movea.l craddr-DB(a6),a1
  2306.         bclr    #0,(a1)     ;stop timer...
  2307.     ENDC
  2308.         clr.l   _module-DB(a6)
  2309.     IFNE    MIDI
  2310.         clr.b   lastcmdbyte-DB(a6)
  2311.     ENDC
  2312.         move.w  _modnum,d1
  2313.         beq.s   PM_modfound
  2314. PM_nextmod  tst.l   mmd_expdata(a0)
  2315.         beq.s   PM_modfound
  2316.         move.l  mmd_expdata(a0),a1
  2317.         tst.l   (a1)
  2318.         beq.s   PM_modfound     ;no more modules here!
  2319.         move.l  (a1),a0
  2320.         subq.w  #1,d1
  2321.         bgt.s   PM_nextmod
  2322. PM_modfound cmp.b   #'T',3(a0)
  2323.         bne.s   PM_nomodT
  2324.         move.b  #'0',3(a0)  ;change MCNT to MCN0
  2325. PM_nomodT   movea.l mmd_songinfo(a0),a1     ;song
  2326.         move.b  msng_tempo2(a1),mmd_counter(a0) ;init counter
  2327.         btst    #0,msng_flags(a1)
  2328.         bne.s   PM_filon
  2329.         bset    #1,$bfe001
  2330.         bra.s   PM_filset
  2331. PM_filon    bclr    #1,$bfe001
  2332. PM_filset   tst.b   d0
  2333.         beq.s   PM_noclr
  2334.         clr.l   mmd_pline(a0)
  2335.         clr.l   rptline-DB(a6)
  2336.         clr.w   blkdelay-DB(a6)
  2337. ; ---------- Set 'pblock' and 'pseq' to correct values...
  2338. PM_noclr    cmp.b   #'2',3(a0)
  2339.         bne.s   PM_oldpbset
  2340.         move.w  mmd_psecnum(a0),d1
  2341.         move.l  a2,-(sp)        ;need extra register
  2342.         movea.l msng_sections(a1),a2
  2343.         add.w   d1,d1
  2344.         move.w  0(a2,d1.w),d1       ;get sequence number
  2345.         add.w   d1,d1
  2346.         add.w   d1,d1
  2347.         move.w  d1,mmd_pseq(a0)
  2348.         movea.l msng_pseqs(a1),a2
  2349.         movea.l 0(a2,d1.w),a2       ;PlaySeq...
  2350.         move.w  mmd_pseqnum(a0),d1
  2351.         add.w   d1,d1
  2352.         move.w  42(a2,d1.w),d1      ;and the correct block..
  2353.         move.l  (sp)+,a2
  2354.         bra.s   PM_setblk
  2355. PM_oldpbset move.w  mmd_pseqnum(a0),d1
  2356.         add.w   #msng_playseq,d1
  2357.         move.b  0(a1,d1.w),d1       ;get first playseq entry
  2358.         ext.w   d1
  2359. PM_setblk   move.w  d1,mmd_pblock(a0)
  2360.         move.w  #-1,mmd_pstate(a0)
  2361.         move.l  a0,_module-DB(a6)
  2362.         btst    #5,msng_flags2(a1)  ;BPM?
  2363.         seq bpmcounter-DB(a6)
  2364.     IFNE    CIAB
  2365.         move.w  msng_deftempo(a1),d0    ;get default tempo
  2366.         movea.l craddr-DB(a6),a1
  2367.         bsr.w   _SetTempo   ;set default tempo
  2368.         bset    #0,(a1)     ;start timer => PLAY!!
  2369.     ENDC
  2370. PM_end      move.l  (sp)+,a6
  2371.         rts
  2372. ; *************************************************************************
  2373.  
  2374. _AudioInit: movem.l a4/a6/d2-d3,-(sp)
  2375.         lea DB,a4
  2376.         moveq   #0,d2
  2377.         movea.l 4.w,a6
  2378. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ alloc signal bit
  2379.     IFNE    AUDDEV
  2380.         moveq   #1,d2
  2381.         moveq   #-1,d0
  2382.         jsr -$14a(a6)   ;AllocSignal()
  2383.         tst.b   d0
  2384.         bmi.w   initerr
  2385.         move.b  d0,sigbitnum-DB(a4)
  2386. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ prepare IORequest
  2387.         lea allocport-DB(a4),a1
  2388.         move.b  d0,15(a1)   ;set mp_SigBit
  2389.         move.l  a1,-(sp)
  2390.         suba.l  a1,a1
  2391.         jsr -$126(a6)   ;FindTask(0)
  2392.         move.l  (sp)+,a1
  2393.         move.l  d0,16(a1)   ;set mp_SigTask
  2394.         lea reqlist-DB(a4),a0
  2395.         move.l  a0,(a0)     ;NEWLIST begins...
  2396.         addq.l  #4,(a0)
  2397.         clr.l   4(a0)
  2398.         move.l  a0,8(a0)    ;NEWLIST ends...
  2399. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ open audio.device
  2400.         moveq   #2,d2
  2401.         lea allocreq-DB(a4),a1
  2402.         lea audiodevname-DB(a4),a0
  2403.         moveq   #0,d0
  2404.         moveq   #0,d1
  2405.         movea.l 4.w,a6
  2406.         jsr -$1bc(a6)   ;OpenDevice()
  2407.         tst.b   d0
  2408.         bne.w   initerr
  2409.         st  audiodevopen-DB(a4)
  2410. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ open cia resource
  2411.         moveq   #3,d2
  2412.     ENDC
  2413.     IFNE    CIAB
  2414.         cmp.b   #50,$212(a6)    ;ExecBase->VBlankFrequency
  2415.         beq.s   init_pal
  2416.         move.l  #474326,timerdiv-DB(a4) ;Assume that CIA freq is 715 909 Hz
  2417.         move.l  #3579545/2,bpmdiv-DB(a4)
  2418. init_pal    moveq   #0,d3
  2419.         lea cianame-DB(a4),a1
  2420.         move.b  #'a',3(a1)
  2421. open_ciares moveq   #0,d0
  2422.         jsr -$1f2(a6)   ;OpenResource()
  2423.         move.l  d0,_ciaresource
  2424.         beq.s   try_CIAB
  2425.         moveq   #4,d2
  2426.         move.l  d0,a6
  2427.         lea timerinterrupt-DB(a4),a1
  2428.         moveq   #0,d0       ;Timer A
  2429.         jsr -$6(a6)     ;AddICRVector()
  2430.         tst.l   d0
  2431.         beq.s   got_timer
  2432.         addq.l  #4,d3       ;add base addr index
  2433.         lea timerinterrupt-DB(a4),a1
  2434.         moveq   #1,d0       ;Timer B
  2435.         jsr -$6(a6)     ;AddICRVector()
  2436.         tst.l   d0
  2437.         beq.s   got_timer
  2438. try_CIAB    lea cianame-DB(a4),a1
  2439.         cmp.b   #'a',3(a1)
  2440.         bne.s   initerr
  2441.         addq.b  #1,3(a1)
  2442.         moveq   #8,d3       ;CIAB base addr index = 8
  2443.         bra.w   open_ciares
  2444. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ attach interrupt
  2445. got_timer   lea craddr+8-DB(a4),a6
  2446.         move.l  cia_addr(pc,d3.w),d0
  2447.         move.l  d0,(a6)
  2448.         sub.w   #$100,d0
  2449.         move.l  d0,-(a6)
  2450.         moveq   #2,d3       ;assume timer B
  2451.         btst    #9,d0       ;timer A or B ?
  2452.         bne.s   got_timerB
  2453.         subq.b  #1,d3       ;not timer B -> subtract 1
  2454.         add.w   #$100,d0    ;calc offset to timer control reg
  2455. got_timerB  add.w   #$900,d0
  2456.         move.l  d0,-(a6)
  2457.         move.l  d0,a0           ;get Control Register
  2458.         and.b   #%10000000,(a0)     ;clear CtrlReg bits 0 - 6
  2459.         move.b  d3,_timeropen-DB(a4)    ;d3: 1 = TimerA 2 = TimerB
  2460.     ENDC
  2461.     IFNE    VBLANK
  2462.         moveq   #5,d0       ;INTB_VERTB
  2463.         lea timerinterrupt-DB(a4),a1
  2464.         jsr -$a8(a6)    ;AddIntServer
  2465.         st  _timeropen-DB(a4)
  2466.     ENDC
  2467.         moveq   #0,d0
  2468. initret:    movem.l (sp)+,a4/a6/d2-d3
  2469.         rts
  2470. initerr:    move.l  d2,d0
  2471.         bra.s   initret
  2472.  
  2473. cia_addr:   dc.l    $BFE501,$BFE701,$BFD500,$BFD700
  2474.  
  2475. _AudioRem:  movem.l a5-a6,-(sp)
  2476.         lea DB,a5
  2477.         moveq   #0,d0
  2478.         move.b  _timeropen,d0
  2479.         beq.s   rem1
  2480. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ remove interrupt
  2481.         clr.b   _timeropen
  2482.     IFNE    CIAB
  2483.         move.l  _ciaresource,a6
  2484.         lea timerinterrupt-DB(a5),a1
  2485.         subq.b  #1,d0
  2486.         jsr -$c(a6)     ;RemICRVector
  2487.     ENDC
  2488.     IFNE    VBLANK
  2489.         movea.l 4.w,a6
  2490.         lea timerinterrupt(pc),a1
  2491.         moveq   #5,d0
  2492.         jsr -$ae(a6)    ;RemIntServer
  2493.     ENDC
  2494. rem1:
  2495.     IFNE    AUDDEV
  2496.         movea.l 4.w,a6
  2497.         tst.b   audiodevopen-DB(a5)
  2498.         beq.s   rem2
  2499.         move.w  #$000f,$dff096  ;stop audio DMA
  2500. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ close audio.device
  2501.         lea allocreq-DB(a5),a1
  2502.         jsr -$1c2(a6)   ;CloseDevice()
  2503.         clr.b   audiodevopen-DB(a5)
  2504. rem2:       moveq   #0,d0
  2505.         move.b  sigbitnum-DB(a5),d0
  2506.         bmi.s   rem3
  2507. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ free signal bit
  2508.         jsr -$150(a6)   ;FreeSignal()
  2509.         st  sigbitnum-DB(a5)
  2510. rem3:
  2511.     ENDC
  2512.         movem.l (sp)+,a5-a6
  2513.         rts
  2514.  
  2515.     IFNE    MIDI
  2516. _GetSerial: movem.l a5-a6,-(sp) ;Get serial port for MIDI
  2517.         lea DB,a5
  2518.         bsr.s   GetSer2
  2519.         tst.l   d0      ;got the port??
  2520.         beq.s   rgser       ;yes
  2521.         movea.l 4.w,a6      ;no..try to flush serial.device:
  2522.         jsr -$84(a6)        ;Forbid
  2523.         lea $15e(a6),a0     ;ExecBase->DeviceList
  2524.         lea serdev-DB(a5),a1    ;"serial.device"
  2525.         jsr -$114(a6)       ;FindName
  2526.         tst.l   d0
  2527.         beq.s   serdnotf        ;no serial.device!!
  2528.         move.l  d0,a1
  2529.         jsr -$1b6(a6)       ;RemDevice
  2530. serdnotf:   jsr -$8a(a6)        ;and Permit
  2531.         bsr.s   GetSer2     ;now try it again...
  2532. rgser:      movem.l (sp)+,a5-a6
  2533.         rts
  2534.  
  2535. GetSer2:    movea.l 4.w,a6
  2536.         moveq   #0,d0
  2537.         lea miscresname-DB(a5),a1
  2538.         jsr -$1f2(a6)   ;OpenResource()
  2539.         move.l  d0,miscresbase-DB(a5)
  2540.         tst.l   d0
  2541.         beq.s   gserror
  2542.         move.l  d0,a6
  2543.         lea medname-DB(a5),a1
  2544.         moveq   #0,d0       ;serial port
  2545.         jsr -$6(a6)     ;AllocMiscResource()
  2546.         tst.l   d0
  2547.         bne.s   gserror
  2548.         lea medname-DB(a5),a1
  2549.         moveq   #1,d0       ;serial bits
  2550.         jsr -$6(a6)
  2551.         tst.l   d0
  2552.         beq.s   gs2_allocok
  2553.         moveq   #0,d0
  2554.         jsr -$c(a6)     ;bits failed -> Free serial port
  2555.         bra.s   gserror
  2556. gs2_allocok move.w  $dff01c,d0
  2557.         btst    #0,d0
  2558.         sne intrson-DB(a5)
  2559.         moveq   #0,d0       ;TBE
  2560.         lea serinterrupt-DB(a5),a1
  2561.         move.l  4.w,a6
  2562.         jsr -$a2(a6)    ;SetIntVector()
  2563.         move.l  d0,prevtbe-DB(a5)
  2564.         move.w  #$8001,$dff09a  ;TBE on
  2565.         move.w  #114,$dff032    ;set baud rate (SERPER)
  2566.         st  serportalloc-DB(a5)
  2567.         moveq   #0,d0
  2568.         rts
  2569. gserror:    moveq   #-1,d0
  2570.         rts
  2571.  
  2572. _FreeSerial:    movem.l a5-a6,-(sp)
  2573.         lea DB,a5
  2574.         tst.l   miscresbase-DB(a5)
  2575.         beq.s   retfs
  2576.         tst.b   serportalloc-DB(a5)
  2577.         beq.s   retfs
  2578. wmb_loop    move.w  $dff018,d0  ;WAIT until all data sent
  2579.         btst    #12,d0      ;test TSRE bit of SERDAT
  2580.         beq.s   wmb_loop
  2581.         move.w  #$0001,$dff09a  ;disable TBE
  2582.         movea.l 4.w,a6
  2583.         move.l  prevtbe-DB(a5),a1
  2584.         moveq   #0,d0
  2585.         jsr -$a2(a6)    ;SetIntVector()
  2586. fs_noptbe   movea.l miscresbase-DB(a5),a6
  2587.         moveq   #0,d0       ;serial port
  2588.         jsr -$c(a6)     ;FreeMiscResource()
  2589.         moveq   #1,d0       ;serial bits
  2590.         jsr -$c(a6)
  2591.         clr.b   serportalloc-DB(a5)
  2592.         clr.b   lastcmdbyte-DB(a5)
  2593. retfs:      movem.l (sp)+,a5-a6
  2594.         rts
  2595.  
  2596. ; Message number in d0.
  2597. _InitMIDIDump:  tst.b   serportalloc
  2598.         beq.s   idd_rts
  2599.         movem.l a5/a6,-(sp) ;a1 = data pointer, d1 = length
  2600.         lea DB,a5
  2601.         movea.l 4.w,a6          ;ExecBase
  2602.         jsr -$78(a6)        ;Disable()
  2603.         cmp.w   #16,dqentries-DB(a5)    ;dump queue full?
  2604.         bge.s   idd_exit        ;exit without doing anything
  2605.         lea dqwriteptr-DB(a5),a1
  2606.         movea.l (a1),a0
  2607.         move.w  d0,(a0)+        ;store message number
  2608.         cmpa.l  a1,a0           ;queue end?
  2609.         bne.s   idd_noresetbuff
  2610.         lea dumpqueue-DB(a5),a0 ;reset write pointer
  2611. idd_noresetbuff move.l  a0,(a1)         ;and write it back.
  2612.         addq.w  #1,dqentries-DB(a5)
  2613.         tst.b   sysx-DB(a5)     ;already sending data?
  2614.         bne.s   idd_exit        ;yes. Don't initiate new send.
  2615.         clr.b   lastcmdbyte-DB(a5)
  2616.         bsr StartNewDump
  2617.         move.w  $dff018,d0      ;SERDATR
  2618.         btst    #13,d0
  2619.         beq.s   idd_exit
  2620.         move.w  #$8001,$dff09c      ;request TBE
  2621. idd_exit    jsr -$7e(a6)        ;Enable()
  2622.         movem.l (sp)+,a5/a6
  2623. idd_rts     rts
  2624.  
  2625. SerIntHandler:  move.w  #$4000,$9a(a0)  ;disable..(Interrupts are enabled anyway)
  2626.         move.w  #1,$9c(a0)          ;clear intreq bit
  2627.         tst.b   sysx-buffptr(a1)        ;sysx??
  2628.         bne.s   sih_sysx
  2629.         move.w  bytesinbuff-buffptr(a1),d0  ;bytesinbuff
  2630.         beq.s   exsih               ;buffer empty
  2631.         movea.l readbuffptr-buffptr(a1),a5  ;get buffer read pointer
  2632.         move.w  #$100,d1            ;Stop bit
  2633.         move.b  (a5)+,d1            ;get byte
  2634.         move.w  d1,$30(a0)          ;and push it to SERDAT
  2635.         cmpa.l  a1,a5               ;shall we reset ptr?
  2636.         bne.s   norrbuffptr         ;not yet..
  2637.         lea -256(a1),a5
  2638. norrbuffptr subq.w  #1,d0               ;one less bytes in buffer
  2639.         move.w  d0,bytesinbuff-buffptr(a1)  ;remember it
  2640.         move.l  a5,readbuffptr-buffptr(a1)  ;push new read ptr back
  2641. exsih       move.w  #$c000,$9a(a0)
  2642.         rts
  2643. sih_sysx    move.w  #$100,d1
  2644.         movea.l sysxptr-buffptr(a1),a5  ;data pointer
  2645.         move.b  (a5)+,d1
  2646.         move.l  a5,sysxptr-buffptr(a1)
  2647.         move.w  d1,$30(a0)      ;-> SERDAT
  2648.         subq.l  #1,sysxleft-buffptr(a1) ;sub data left length
  2649.         bne.s   exsih       ;not 0w
  2650.         lea DB,a5
  2651.         clr.b   lastcmdbyte-DB(a5)
  2652.         bsr.s   StartNewDump
  2653.         bra.s   exsih
  2654.  
  2655. StartNewDump:   tst.w   dqentries-DB(a5)    ;queue empty?
  2656.         beq.s   snd_exit2
  2657.         movea.l dqreadptr-DB(a5),a1 ;get read pointer
  2658.         move.w  (a1)+,d0        ;get message number (D0)
  2659.         cmpa.l  #dqwriteptr,a1      ;queue end?
  2660.         bne.s   snd_noresetbuff
  2661.         lea dumpqueue-DB(a5),a1 ;reset write pointer
  2662. snd_noresetbuff move.l  a1,dqreadptr-DB(a5) ;and write it back.
  2663.         subq.w  #1,dqentries-DB(a5)
  2664. ; then attempt to search the given message (# in D0)
  2665.         move.l  _module-DB(a5),d1
  2666.         beq.s   StartNewDump
  2667.         move.l  d1,a1
  2668.         move.l  mmd_expdata(a1),d1
  2669.         beq.s   StartNewDump
  2670.         move.l  d1,a1
  2671.         move.l  52(a1),d1       ;exp_dump
  2672.         beq.s   StartNewDump
  2673.         move.l  d1,a1
  2674.         cmp.w   (a1),d0
  2675.         bge.s   StartNewDump
  2676.         addq.l  #8,a1           ;points to MMDDump ptr table
  2677.         add.w   d0,d0
  2678.         add.w   d0,d0           ;number *= 4
  2679.         adda.w  d0,a1
  2680.         movea.l (a1),a1
  2681. ; initialize send variables (msg addr. in A0)
  2682. snd_found   move.l  (a1)+,sysxleft-DB(a5)   ;length
  2683.         move.l  (a1),sysxptr-DB(a5) ;data pointer
  2684.         st  sysx-DB(a5)
  2685.         rts
  2686. snd_exit2   clr.b   sysx-DB(a5)     ;finish dump
  2687.         rts
  2688.  
  2689. _AddMIDIData    move.l  a6,-(sp)
  2690.         lea DB,a6
  2691.         bsr.s   _AddMIDId
  2692.         move.l  (sp)+,a6
  2693.         rts
  2694.  
  2695. _AddMIDId   movem.l a2-a3/a5,-(sp)
  2696.         tst.b   serportalloc-DB(a6)
  2697.         beq.s   retamd1
  2698.         movea.l 4.w,a5
  2699.         lea $dff09a,a3
  2700.         move.w  #$4000,(a3) ;Disable interrupts
  2701.         addq.b  #1,$126(a5) ;ExecBase->IDNestCnt
  2702.         lea buffptr-DB(a6),a2   ;end of buffer (ptr)
  2703.         move.w  -130(a3),d1 ;-130(a3) = $dff018 (SERDATR)
  2704.         btst    #13,d1
  2705.         beq.s   noTBEreq
  2706.         move.w  #$8001,2(a3)    ;request TBE [2(a3) = $dff09c]
  2707. noTBEreq    movea.l (a2),a1     ;buffer pointer
  2708.         subq.w  #1,d0       ;-1 for DBF
  2709. adddataloop move.b  (a0)+,d1    ;get byte
  2710.         bpl.s   norscheck   ;this isn't a status byte
  2711.         cmp.b   #$ef,d1     ;ignore system messages
  2712.         bhi.s   norscheck
  2713.         cmp.b   lastcmdbyte-DB(a6),d1   ;same as previous status byte?
  2714.         beq.s   samesb          ;yes, skip
  2715.         move.b  d1,lastcmdbyte-DB(a6)   ;no, don't skip but store.
  2716. norscheck   move.b  d1,(a1)+        ;push to midi send buffer
  2717.         addq.w  #1,8(a2)
  2718. samesb      cmpa.l  a2,a1           ;end of buffer??
  2719.         bne.s   noresbuffptr        ;no.
  2720.         lea sendbuffer-DB(a6),a1    ;reset
  2721. noresbuffptr    dbf d0,adddataloop
  2722.         move.l  a1,(a2)         ;push back new buffer ptr
  2723.         subq.b  #1,$126(a5)
  2724.         bge.s   retamd1
  2725.         move.w  #$c000,(a3) ;enable interrupts again
  2726. retamd1     movem.l (sp)+,a2-a3/a5
  2727.         rts
  2728.     ENDC
  2729.  
  2730.         DATA
  2731. DB:     ;Data base pointer
  2732.     IFNE    MIDI
  2733. sendbuffer  ds.b    256
  2734. buffptr     dc.l    sendbuffer
  2735. readbuffptr dc.l    sendbuffer
  2736. bytesinbuff dc.w    0
  2737. sysx        dc.b    0
  2738. lastcmdbyte dc.b    0
  2739. sysxptr     dc.l    0
  2740. sysxleft    dc.l    0
  2741. dumpqueue   ds.w    16
  2742. dqwriteptr  dc.l    dumpqueue
  2743. dqreadptr   dc.l    dumpqueue
  2744. dqentries   dc.w    0
  2745.     ENDC
  2746. miscresbase dc.l    0
  2747. timerdiv    dc.l    470000
  2748.     IFNE    AUDDEV
  2749. audiodevopen    dc.b    0
  2750. sigbitnum   dc.b    -1
  2751.     ENDC
  2752.     IFNE    MIDI
  2753. serportalloc    dc.b    0
  2754.     ENDC
  2755.         even
  2756.     IFNE    MIDI
  2757. preschgdata dc.l    0
  2758. noteondata  dc.l    0
  2759.     ENDC
  2760. _module     dc.l    0
  2761. dmaonmsk    dc.w    0 ;\_May not be
  2762.     IFNE    MIDI
  2763. bytesinnotebuff dc.w    0 ;/ separated!
  2764. noteonbuff  ds.b    (MAX_NUMTRACKS+2)*3
  2765.         even
  2766. intrson     dc.b    0,0
  2767. prevtbe     dc.l    0
  2768.     ENDC
  2769.     IFNE    CIAB
  2770. _ciaresource    dc.l    0
  2771. craddr      dc.l    0
  2772.         dc.l    0   ;tloaddr
  2773.         dc.l    0   ;thiaddr
  2774.     ENDC
  2775. timerinterrupt  dc.w    0,0,0,0,0
  2776.         dc.l    timerintname,DB
  2777.         dc.l    _IntHandler
  2778.     IFNE    MIDI
  2779. serinterrupt    dc.w    0,0,0,0,0
  2780.         dc.l    serintname,buffptr,SerIntHandler
  2781.     ENDC
  2782.     IFNE    AUDDEV
  2783. allocport   dc.l    0,0 ;succ, pred
  2784.         dc.b    4,0 ;NT_MSGPORT
  2785.         dc.l    0   ;name
  2786.         dc.b    0,0 ;flags = PA_SIGNAL
  2787.         dc.l    0   ;task
  2788. reqlist     dc.l    0,0,0   ;list head, tail and tailpred
  2789.         dc.b    5,0
  2790. allocreq    dc.l    0,0
  2791.         dc.b    0,127   ;NT_UNKNOWN, use maximum priority (127)
  2792.         dc.l    0,allocport ;name, replyport
  2793.         dc.w    68      ;length
  2794.         dc.l    0   ;io_Device
  2795.         dc.l    0   ;io_Unit
  2796.         dc.w    0   ;io_Command
  2797.         dc.b    0,0 ;io_Flags, io_Error
  2798.         dc.w    0   ;ioa_AllocKey
  2799.         dc.l    sttempo ;ioa_Data
  2800.         dc.l    1   ;ioa_Length
  2801.         dc.w    0,0,0   ;ioa_Period, Volume, Cycles
  2802.         dc.w    0,0,0,0,0,0,0,0,0,0 ;ioa_WriteMsg
  2803. audiodevname    dc.b    'audio.device',0
  2804.     ENDC
  2805.     IFNE    CIAB
  2806. cianame     dc.b    'ciax.resource',0
  2807. _timeropen  dc.b    0
  2808.     ENDC
  2809. timerintname    dc.b    'OMEDTimerInterrupt',0
  2810.     IFNE    MIDI
  2811. serintname  dc.b    'OMEDSerialInterrupt',0
  2812. miscresname dc.b    'misc.resource',0
  2813. serdev      dc.b    'serial.device',0
  2814. medname     dc.b    'OctaMED Pro modplayer',0
  2815.     ENDC
  2816.         even
  2817.     IFNE    MIDI
  2818. midiresd    dc.b    $e0,$00,$40,$b0,$01,$00
  2819.  
  2820. midicontrnum    ds.b    16
  2821.  
  2822. prevmidicpres   dc.l    0,0,0,0,0,0,0,0 ; 16 * 2 bytes
  2823.  
  2824. prevmidipbend   dc.w    $2000,$2000,$2000,$2000,$2000,$2000,$2000,$2000
  2825.         dc.w    $2000,$2000,$2000,$2000,$2000,$2000,$2000,$2000
  2826.     ENDC
  2827. ; TRACK-data structures (see definitions at the end of this file)
  2828. t03d        ds.b    22
  2829.         dc.l    $dff0a0
  2830.         ds.b    71
  2831.         dc.b    $ff
  2832.         ds.b    22
  2833.         dc.l    $dff0b0
  2834.         ds.b    71
  2835.         dc.b    $ff
  2836.         ds.b    22
  2837.         dc.l    $dff0c0
  2838.         ds.b    71
  2839.         dc.b    $ff
  2840.         ds.b    22
  2841.         dc.l    $dff0d0
  2842.         ds.b    71
  2843.         dc.b    $ff
  2844. t463d       ds.b    (MAX_NUMTRACKS-4)*T415SZ
  2845. trackdataptrs   dc.l    t03d,t03d+T03SZ,t03d+2*T03SZ,t03d+3*T03SZ
  2846. ; Build pointer table. This works on Devpac assembler, other assemblers
  2847. ; may need modifications.
  2848. TRKCOUNT    SET 0
  2849.         REPT    (MAX_NUMTRACKS-4)
  2850.         dc.l    t463d+TRKCOUNT
  2851. TRKCOUNT    SET TRKCOUNT+T415SZ
  2852.         ENDR
  2853.  
  2854. nextblock   dc.b    0 ;\ DON'T SEPARATE
  2855. nxtnoclrln  dc.b    0 :/
  2856. numtracks   dc.w    0 ;\ DON'T SEPARATE
  2857. numlines    dc.w    0 ;/
  2858. nextblockline   dc.w    0
  2859. rptline     dc.w    0 ;\ DON'T SEPARATE
  2860. rptcounter  dc.w    0 ;/
  2861. blkdelay    dc.w    0   ;block delay (PT PatternDelay)
  2862. bpmcounter  dc.w    0
  2863. bpmdiv      dc.l    3546895/2
  2864.  
  2865. ; Fields in struct InstrExt (easier to access this way rather than
  2866. ; searching through the module).
  2867. holdvals    ds.b 63
  2868. decays      ds.b 63
  2869. finetunes   ds.b 63
  2870. flags       ds.b 63
  2871. ext_midipsets   ds.w 63
  2872.  
  2873. ; Below are the period tables. There's one table for each finetune position.
  2874.     IFNE    SYNTH|IFFMOCT
  2875.     dc.w    3424,3232,3048,2880,2712,2560,2416,2280,2152,2032,1920,1812
  2876.     dc.w    1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906
  2877.     ENDC
  2878. per0    dc.w    856,808,762,720,678,640,604,570,538,508,480,453
  2879.     dc.w    428,404,381,360,339,320,302,285,269,254,240,226
  2880.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2881.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2882.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2883.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2884.     IFNE    SYNTH|IFFMOCT
  2885.     dc.w    3400,3209,3029,2859,2699,2547,2404,2269,2142,2022,1908,1801
  2886.     dc.w    1700,1605,1515,1430,1349,1274,1202,1135,1071,1011,954,901
  2887.     ENDC
  2888. per1    dc.w    850,802,757,715,674,637,601,567,535,505,477,450
  2889.     dc.w    425,401,379,357,337,318,300,284,268,253,239,225
  2890.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2891.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2892.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2893.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2894.     IFNE    SYNTH|IFFMOCT
  2895.     dc.w    3376,3187,3008,2839,2680,2529,2387,2253,2127,2007,1895,1788
  2896.     dc.w    1688,1593,1504,1419,1340,1265,1194,1127,1063,1004,947,894
  2897.     ENDC
  2898. per2    dc.w    844,796,752,709,670,632,597,563,532,502,474,447
  2899.     dc.w    422,398,376,355,335,316,298,282,266,251,237,224
  2900.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2901.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2902.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2903.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2904.     IFNE    SYNTH|IFFMOCT
  2905.     dc.w    3352,3164,2986,2819,2660,2511,2370,2237,2112,1993,1881,1776
  2906.     dc.w    1676,1582,1493,1409,1330,1256,1185,1119,1056,997,941,888
  2907.     ENDC
  2908. per3    dc.w    838,791,746,704,665,628,592,559,528,498,470,444
  2909.     dc.w    419,395,373,352,332,314,296,280,264,249,235,222
  2910.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2911.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2912.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2913.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2914.     IFNE    SYNTH|IFFMOCT
  2915.     dc.w    3328,3141,2965,2799,2641,2493,2353,2221,2097,1979,1868,1763
  2916.     dc.w    1664,1571,1482,1399,1321,1247,1177,1111,1048,989,934,881
  2917.     ENDC
  2918. per4    dc.w    832,785,741,699,660,623,588,555,524,495,467,441
  2919.     dc.w    416,392,370,350,330,312,294,278,262,247,233,220
  2920.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2921.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2922.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2923.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2924.     IFNE    SYNTH|IFFMOCT
  2925.     dc.w    3304,3119,2944,2778,2622,2475,2336,2205,2081,1965,1854,1750
  2926.     dc.w    1652,1559,1472,1389,1311,1238,1168,1103,1041,982,927,875
  2927.     ENDC
  2928. per5    dc.w    826,779,736,694,655,619,584,551,520,491,463,437
  2929.     dc.w    413,390,368,347,328,309,292,276,260,245,232,219
  2930.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2931.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2932.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2933.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2934.     IFNE    SYNTH|IFFMOCT
  2935.     dc.w    3280,3096,2922,2758,2603,2457,2319,2189,2066,1950,1841,1738
  2936.     dc.w    1640,1548,1461,1379,1302,1229,1160,1095,1033,975,920,869
  2937.     ENDC
  2938. per6    dc.w    820,774,730,689,651,614,580,547,516,487,460,434
  2939.     dc.w    410,387,365,345,325,307,290,274,258,244,230,217
  2940.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2941.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2942.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2943.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2944.     IFNE    SYNTH|IFFMOCT
  2945.     dc.w    3256,3073,2901,2738,2584,2439,2302,2173,2051,1936,1827,1725
  2946.     dc.w    1628,1537,1450,1369,1292,1220,1151,1087,1026,968,914,862
  2947.     ENDC
  2948. per7    dc.w    814,768,725,684,646,610,575,543,513,484,457,431
  2949.     dc.w    407,384,363,342,323,305,288,272,256,242,228,216
  2950.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2951.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2952.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2953.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2954.     IFNE    SYNTH|IFFMOCT
  2955.     dc.w    3628,3424,3232,3051,2880,2718,2565,2421,2285,2157,2036,1922
  2956.     dc.w    1814,1712,1616,1525,1440,1359,1283,1211,1143,1079,1018,961
  2957.     ENDC
  2958. per_8   dc.w    907,856,808,762,720,678,640,604,570,538,508,480
  2959.     dc.w    453,428,404,381,360,339,320,302,285,269,254,240
  2960.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2961.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2962.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2963.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2964.     IFNE    SYNTH|IFFMOCT
  2965.     dc.w    3588,3387,3197,3017,2848,2688,2537,2395,2260,2133,2014,1901
  2966.     dc.w    1794,1693,1598,1509,1424,1344,1269,1197,1130,1067,1007,950
  2967.     ENDC
  2968. per_7   dc.w    900,850,802,757,715,675,636,601,567,535,505,477
  2969.     dc.w    450,425,401,379,357,337,318,300,284,268,253,238
  2970.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2971.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2972.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2973.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2974.     IFNE    SYNTH|IFFMOCT
  2975.     dc.w    3576,3375,3186,3007,2838,2679,2529,2387,2253,2126,2007,1894
  2976.     dc.w    1788,1688,1593,1504,1419,1339,1264,1193,1126,1063,1003,947
  2977.     ENDC
  2978. per_6   dc.w    894,844,796,752,709,670,632,597,563,532,502,474
  2979.     dc.w    447,422,398,376,355,335,316,298,282,266,251,237
  2980.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2981.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2982.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2983.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2984.     IFNE    SYNTH|IFFMOCT
  2985.     dc.w    3548,3349,3161,2984,2816,2658,2509,2368,2235,2110,1991,1879
  2986.     dc.w    1774,1674,1580,1492,1408,1329,1254,1184,1118,1055,996,940
  2987.     ENDC
  2988. per_5   dc.w    887,838,791,746,704,665,628,592,559,528,498,470
  2989.     dc.w    444,419,395,373,352,332,314,296,280,264,249,235
  2990.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2991.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2992.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2993.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2994.     IFNE    SYNTH|IFFMOCT
  2995.     dc.w    3524,3326,3140,2963,2797,2640,2492,2352,2220,2095,1978,1867
  2996.     dc.w    1762,1663,1570,1482,1399,1320,1246,1176,1110,1048,989,933
  2997.     ENDC
  2998. per_4   dc.w    881,832,785,741,699,660,623,588,555,524,494,467
  2999.     dc.w    441,416,392,370,350,330,312,294,278,262,247,233
  3000.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  3001.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  3002.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  3003.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  3004.     IFNE    SYNTH|IFFMOCT
  3005.     dc.w    3500,3304,3118,2943,2778,2622,2475,2336,2205,2081,1964,1854
  3006.     dc.w    1750,1652,1559,1472,1389,1311,1237,1168,1102,1041,982,927
  3007.     ENDC
  3008. per_3   dc.w    875,826,779,736,694,655,619,584,551,520,491,463
  3009.     dc.w    437,413,390,368,347,328,309,292,276,260,245,232
  3010.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  3011.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  3012.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  3013.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  3014.     IFNE    SYNTH|IFFMOCT
  3015.     dc.w    3472,3277,3093,2920,2756,2601,2455,2317,2187,2064,1949,1839
  3016.     dc.w    1736,1639,1547,1460,1378,1301,1228,1159,1094,1032,974,920
  3017.     ENDC
  3018. per_2   dc.w    868,820,774,730,689,651,614,580,547,516,487,460
  3019.     dc.w    434,410,387,365,345,325,307,290,274,258,244,230
  3020.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  3021.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  3022.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  3023.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  3024.     IFNE    SYNTH|IFFMOCT
  3025.     dc.w    3448,3254,3072,2899,2737,2583,2438,2301,2172,2050,1935,1827
  3026.     dc.w    1724,1627,1536,1450,1368,1292,1219,1151,1086,1025,968,913
  3027.     ENDC
  3028. per_1   dc.w    862,814,768,725,684,646,610,575,543,513,484,457
  3029.     dc.w    431,407,384,363,342,323,305,288,272,256,242,228
  3030.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  3031.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  3032.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  3033.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  3034.  
  3035. _periodtable
  3036.     dc.l    per_8,per_7,per_6,per_5,per_4,per_3,per_2,per_1,per0
  3037.     dc.l    per1,per2,per3,per4,per5,per6,per7
  3038.  
  3039.     IFND    __G2
  3040.         section "datachip",data,chip ;for A68k
  3041.     ENDC
  3042.     IFD __G2
  3043.         section "datachip",data_c ;this is for Devpac 2
  3044.     ENDC
  3045.         XDEF    _modnum
  3046.     IFNE    EASY
  3047. easymod     INCBIN  "module"    ;<<<<< MODULE NAME HERE!
  3048.     ENDC
  3049. _chipzero   dc.l    0
  3050. _modnum     dc.w    0   ;number of module to play
  3051.  
  3052. ; SPECIAL... FREE CHANNEL 0
  3053.         XDEF    _freech0
  3054.  
  3055. _freech0    dc.w    0
  3056.  
  3057. ; the track-data structure definition:
  3058. trk_prevnote    EQU 0   ;previous note number
  3059. trk_previnstr   EQU 1   ;previous instrument number
  3060. trk_prevvol EQU 2   ;previous volume
  3061. trk_prevmidich  EQU 3   ;previous MIDI channel
  3062. trk_cmd     EQU 4   ;command (the 3rd number from right)
  3063. trk_cmdqual EQU 5   ;command qualifier (infobyte, databyte..)
  3064. trk_prevmidin   EQU 6   ;previous MIDI note
  3065. trk_noteoffcnt  EQU 7   ;note-off counter (hold)
  3066. trk_inithold    EQU 8   ;default hold for this instrument
  3067. trk_initdecay   EQU 9   ;default decay for....
  3068. trk_stransp EQU 10  ;instrument transpose
  3069. trk_finetune    EQU 11  ;finetune
  3070. trk_soffset EQU 12  ;new sample offset
  3071. trk_previnstra  EQU 14  ;address of the previous instrument data
  3072. trk_trackvol    EQU 18
  3073. ;   the following data only on tracks 0 - 3
  3074. trk_prevper EQU 20  ;previous period
  3075. trk_audioaddr   EQU 22  ;hardware audio channel base address
  3076. trk_sampleptr   EQU 26  ;pointer to sample
  3077. trk_samplelen   EQU 30  ;length (>> 1)
  3078. trk_porttrgper  EQU 32  ;portamento (cmd 3) target period
  3079. trk_vibshift    EQU 34  ;vibrato shift for ASR instruction
  3080. trk_vibrspd EQU 35  ;vibrato speed/size (cmd 4 qualifier)
  3081. trk_vibrsz  EQU 36  ;vibrato size
  3082. trk_synthptr    EQU 38  ;pointer to synthetic/hybrid instrument
  3083. trk_arpgoffs    EQU 42  ;SYNTH: current arpeggio offset
  3084. trk_arpsoffs    EQU 44  ;SYNTH: arpeggio restart offset
  3085. trk_volxcnt EQU 46  ;SYNTH: volume execute counter
  3086. trk_wfxcnt  EQU 47  ;SYNTH: waveform execute counter
  3087. trk_volcmd  EQU 48  ;SYNTH: volume command pointer
  3088. trk_wfcmd   EQU 50  ;SYNTH: waveform command pointer
  3089. trk_volwait EQU 52  ;SYNTH: counter for WAI (volume list)
  3090. trk_wfwait  EQU 53  ;SYNTH: counter for WAI (waveform list)
  3091. trk_synthvibspd EQU 54  ;SYNTH: vibrato speed
  3092. trk_wfchgspd    EQU 56  ;SYNTH: period change
  3093. trk_perchg  EQU 58  ;SYNTH: curr. period change from trk_prevper
  3094. trk_envptr  EQU 60  ;SYNTH: envelope waveform pointer
  3095. trk_synvibdep   EQU 64  ;SYNTH: vibrato depth
  3096. trk_synvibwf    EQU 66       ;SYNTH: vibrato waveform
  3097. trk_synviboffs  EQU 70  ;SYNTH: vibrato pointer
  3098. trk_initvolxspd EQU 72  ;SYNTH: volume execute speed
  3099. trk_initwfxspd  EQU 73  ;SYNTH: waveform execute speed
  3100. trk_volchgspd   EQU 74  ;SYNTH: volume change
  3101. trk_prevnote2   EQU 75  ;SYNTH: previous note
  3102. trk_synvol  EQU 76  ;SYNTH: current volume
  3103. trk_synthtype   EQU 77  ;>0 = synth, -1 = hybrid, 0 = no synth
  3104. trk_periodtbl   EQU 78  ;pointer to period table
  3105. trk_prevportspd EQU 82  ;portamento (cmd 3) speed
  3106. trk_decay   EQU 84  ;decay
  3107. trk_fadespd EQU 85  ;decay speed
  3108. trk_envrestart  EQU 86  ;SYNTH: envelope waveform restart point
  3109. trk_envcount    EQU 90  ;SYNTH: envelope counter
  3110. trk_split   EQU 91  ;0 = this channel not splitted (OctaMED V2)
  3111. trk_vibroffs    EQU 92  ;vibrato table offset \ DON'T SEPARATE
  3112. trk_tremoffs    EQU 93  ;tremolo table offset /
  3113. trk_tremsz  EQU 94  ;tremolo size
  3114. trk_tremspd EQU 96  ;tremolo speed
  3115. trk_tempvol EQU 97  ;temporary volume (for tremolo)
  3116.         END